跳转到内容
新建笔记

Keil printf 重定向到 STM32 UART:运行库与 fputc

printf 先完成格式化,再通过所用 C 运行库的底层输出入口发送字符。选择 MicroLIB 决定运行库实现,重定向决定字符送到 UART、调试通道还是别处,两件事不应混为一谈。Keil 文档区分了高层格式化、底层字符 I/O 和系统 I/O;MicroLIB 的接口也与默认库不同。MDK5 手册

原截图为 ARM Compiler 5 工程中的 Use MicroLIB。AC5、AC6、GCC/newlib 等工具链的重定向入口可能不同,以下仅作为采用 fputc 路径的 Keil/MicroLIB 工程示例。

假设 CubeMX 工程已生成 usart.h,其中声明 huart1,并且 HAL 与 UART1 已初始化:

#include <stdio.h>
#include <stdint.h>
#include "usart.h"
int fputc(int ch, FILE *stream)
{
(void)stream;
uint8_t byte = (uint8_t)ch;
if (HAL_UART_Transmit(&huart1, &byte, 1, 100) != HAL_OK) {
return EOF;
}
return byte;
}

原例把 int ch 的地址强制转换后发送一个字节,依赖存储表示。本版先转换成明确的 uint8_t,并处理 HAL 发送失败。超时 100 的具体时间基准按该 HAL 的配置理解;高频日志不宜逐字符阻塞发送。

  1. 确认串口引脚、时钟、波特率和终端设置匹配。
  2. 先用 HAL 发送固定字节串,验证硬件链路。
  3. 再调用 printf("value=%d\r\n", 123);,核对链接到的输出入口。
  4. 如果发生半主机相关异常或无输出,检查运行库配置和已有 retarget 文件,避免重复定义函数。

该示例用于普通线程/主循环中的低频调试,不放到中断中长时间阻塞;多任务并发输出还需要串行化。DMA 或中断发送需要保证缓冲区在发送完成前有效,不能把当前局部 byte 指针直接交给异步发送后立即返回。

涉及浮点格式、文件流或更完整标准库行为时,应对照具体运行库支持范围。ARM Compiler 5 库说明

本笔记由 CSDN 原始记录 的文字与图片重新整理;正文中的代码、适用条件与说明已按本次审读补充。