单片机的printf重定向串口输出调试信息

前言
在 pc 上运行 c 语言时,prinf 输出的内容会打印在电脑显示器上,这是因为 prinf 默认的输出设备就是显示器。而当我们在单片机上,需要通过 printf 函数将信息打印到串口,就要对 printf 函数的输出进行重定向。
printf 输出重定向的方法
printf 函数声明如下:
int printf(const char *format, ...);printf 函数根据 format 字符串给出的格式打印输出到 stdout(标准输出)中,当然,printf 函数是不会一个字符一个字符去输出,它会调用更底层的 i/o 函数去逐个字符打印。
printf 是库函数,不同编译器对 c库的底层实现机制是不同的,因此 printf 中调用了哪个底层 i/o 函数来输出字符,需要根据当前使用的编译器来确定。
我们实现 printf 输出重定向的方法就是找到当前使用的编译器中,printf 调用了哪个底层 i/o 函数来输出字符,再改写该函数,将字符通过串口输出。
如何确定输出字符的底层 i/o 函数?
以 keil 为例,点击菜单栏 help ==> μvision help 选项,打开帮助文档。
如果你是51单片机项目,那么使用的编译器是 keil c51,打开的就是 c51 的帮助文档;如果你是 arm 单片机项目,那么使用的编译器是 keil mdk,打开的就是 arm 的帮助文档。
查找 printf 关键字,可以看到 c51 的 printf 底层是调用 putchar 函数实现字符输出的:
而 arm 的 printf 函数底层是调用 fputc函数实现字符输出的:
从上述的结果可知,要想通过 printf 向串口打印调试信息,c51 单片机需要改写 putchar( ) 函数,而 arm 单片机则需要改写 fputc( ) 函数。
c51 和 arm 项目中,printf 输出重定向的方法是不一样的,这就是有些人把 stm32 的 printf 搬到 c51 中会出错的原因之一。
c51 重定向 printf 输出的注意事项
c51 重定向 printf 函数的输出到串口,需要改写 putchar 函数,伪代码如下:
char putchar (char ch)
{
sbuf0 = ch;
while( !(scon0 & (1< <1)));
scon0 &=~(1< <1);
return 0;
}使用 printf 函数前,需要包含 头文件。
51单片机重定向 printf 函数后,如果直接像 pc机或者是 32位单片机那样使用 %d 占位符打印数值,输出的数值可能是错误的,例如下面的代码输出结果可能就是不正确:
int i = 10; printf(%d, i);keil 中扩展了 b、h、l 来设置字节宽度:
b - 8bith - 16bit (默认)l - 32bit在 keil c51中,用 printf 输出一个单字节变量时,要使用%bd,例如:
unsigned char x = 'a'; printf(x: %bdn, x);这些内容在 keil c51 帮助文档关于 printf 的章节中有提到:
扩展知识
不知道有没小伙伴发现,如果项目中没有重写 putchar 或 fputc 函数,直接调用 printf 也不会报错,只是 printf 打印的内容不知道输出到哪里罢了。
printf 函数里面调用了更加底层的 putchar 或 fputc 函数而没有报错,说明在 c库里面已经实现了 putchar 或 fputc 函数,那为什么我们在 c库外重新实现 putchar 或 fputc 函数时,编译器没有报重复定义的错误呢?
这是因为在 c库里,putchar 或 fputc 函数被定义成了弱函数(weak),当你定义了 putchar 或 fputc 函数,那么编译时就使用你定义的函数,否则就使用 c库中的 putchar 或 fputc 函数。

Silicon Labs Gecko MCU确保Misfit Shine 可穿戴健身追踪器“节能省电”
国产嵌入式工业主板安装的独特优势
蓝牙耳机哪家好?玩和平精英蓝牙耳机推荐
荣耀9什么时候上市?荣耀9最新消息:荣耀9备战小米6,配置惊喜满满
东风本田全球首个纯电智能工厂今年投产
单片机的printf重定向串口输出调试信息
依赖政府补贴,江丰电子、阿石创净利下滑
角度传感器的选择 如何选择角度传感器
宁德时代的总市值已超过7500亿美元
陶瓷PCB在汽车LED行业的应用
i.MX RT600 BCLK受干扰影响WS频率解决方案
波士顿动力机器人组团跳舞:跳舞背后的原理是什么呢
示波器高压探棒—揭秘高品质示波器的关键配件
全球顶尖的11家科技公司全部都在“热火朝天”得搞人工智能
家庭预防近视是关键,研究证明OLED自发光电视蓝光更少更护眼
整流器是如何将交流信号转换为脉冲信号的呢?
雷赛推出中国首创混合伺服驱动器亮相高交会电子展
4G向5G的跨越什么时候可以完成
超级电容器20秒内完成充电,电动汽车不用愁了
WCDMA向后3G演进中基带传输技术