STM32 经典坑:编译0错误0警告,printf却完全不输出(彻底解决)
最近调试 STM32F407 遇到一个超级折磨新手的经典问题:
Keil 编译结果:0 Error、0 Warning,工程完全正常、可以正常烧录。
但是!串口助手**完全没有任何打印信息。
很多新手会误以为:没有报错 = 程序没问题。
但嵌入式开发最大的坑就是:语法没问题 ≠ 配置没问题 ≠ 能正常运行。
今天把这个全网最高频的 printf 失效问题,一次性彻底讲透。
一、我的现象:
-
工程编译:0 错误 0 警告
-
代码逻辑正常,串口初始化写完了
-
烧录成功,程序正常运行
-
串口助手打开正常、波特率匹配(115200 8N1)
-
但是 printf 完全不输出任何数据
二、真正原因
printf 不打印,根本不是代码语法错误,而是三个隐性强制条件没满足。
只要缺一个,printf 直接哑巴。
原因1:没有勾选 Use MicroLIB(最核心原因)
Keil 标准库下,不开启微库,printf 重定向直接失效,而且不报任何错、不警告!
解决:
魔术棒 → Target → 勾选Use MicroLIB
原因2:缺少 fputc 重定向函数
printf 默认输出到屏幕,想要输出到串口,必须手动重定向。
必须在 uart.c 加入这段代码:
#include <stdio.h>
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t)ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return ch;
}
原因3:执行顺序错误(超级低级但超级常见)
错误写法:
printf("test"); //先打印
USART1_Init(); //后初始化串口
串口还没开机就打印,永远无输出!
正确顺序:先初始化串口,再打印
原因4:下载程序后没有按复位键
J-Link 下载完成后,芯片有时继续跑旧代码,新代码不生效。
必须:下载 → 按复位键 → 观察串口输出。
三、硬件层面隐性坑
软件全部正确,依然不打印,看硬件:
-
USB-TTL TX → 单片机 RX
-
USB-TTL RX → 单片机 TX
-
GND 必须共地(不共地绝对不通)
很多新手直接 TX-TX、RX-RX 直连,直接报废串口通信。
四、最简测试代码(一键排查)
用这段代码,只要环境没问题,100%打印成功:
int main(void)
{
USART1_Init();
printf("Hello STM32!\r\n");
while(1)
{
}
}
五、最终总结(超级重要)
嵌入式开发铁律:
0错误0警告 ≠ 程序正常
语法没问题,不代表:
-
库配置正确
-
重定向有效
-
初始化顺序正确
-
硬件接线正确
这次踩坑让我彻底明白:
STM32 最难的不是写代码,是排错。
看似玄学的不打印问题,其实每一步都有标准答案。
六、个人感悟
新手学习嵌入式,最容易自我怀疑的就是:代码没报错,却跑不出现象。
但实际上,大部分问题都不是代码写错了,而是开发环境配置、底层原理、硬件常识不到位。
搞定这个问题,相当于入门 STM32 串口调试毕业了!
浙公网安备 33010602011771号