printf重定向:一句fputc,串口打印任意变量

短文标题:printf重定向:一句fputc,串口打印任意变量

你有没有想过一个问题:电脑上调试程序,用printf直接打印变量值,一目了然。

单片机没有显示器,怎么实现类似的效果?重定向printf到串口。 把printf这个"输出口",从电脑屏幕"拧"到单片机的USART上。重定向fputc,printf底层会调用fputc输出每一个字符。我们只需要重写fputc,把字符通过USART发送出去:

int fputc(int ch, FILE *f)

{

while (!(USART1->SR & USART_SR_TXE)); // 等待上次发送完成

USART1->DR = (uint8_t)ch; // 发送字符

return ch;

}

写好这个函数,就可以直接用printf了:

int temperature = 25;

printf("当前温度: %d 度\r\n", temperature);

串口调试助手就能看到"当前温度: 25 度"。浮点数(%f)支持需额外配置(MicroLIB默认不支持)。MicroLIB:必须勾选的关键,在MDK(Keil)中,只用fputc还不够。必须勾选Use MicroLIB(微库)。否则链接时会报错,或运行时卡死。MicroLIB是ARM为嵌入式设备精简的C库,移除了半主机依赖,体积小。

半主机模式的陷阱,ARM标准库默认支持"半主机模式"(通过调试器与主机通信,如printf输出到IDE的Debug Viewer)。单片机独立运行时没有调试器,半主机模式会让程序卡死。勾选MicroLIB(禁用半主机),或手动实现__FILE结构体的桩函数,让半主机失效。MicroLIB最简单,推荐。

MicroLIB的限制

• 不支持浮点数(%f):浮点转字符串代码体积大,MicroLIB默认不包含。变通:整数部分和小数部分分开打印

int temp_x10 = 261;

printf("温度: %d.%d℃\r\n", temp_x10 / 10, temp_x10 % 10);

• 不支持宽字符

• 部分标准函数功能简化

对嵌入式调试而言,这些限制通常可接受。多串口支持,需要同时使用多个串口(如USART1打印日志,USART2通信),可自定义类printf函数,传入串口句柄:

int printf_usart(UART_HandleTypeDef *huart, const char *format, ...)

{

char buf256;

va_list args;

va_start(args, format);

int len = vsnprintf(buf, sizeof(buf), format, args);

va_end(args);

HAL_UART_Transmit(huart, (uint8_t*)buf, len, 100);

return len;

}

这个故事的启示,重定向fputc是用标准库实现硬件输出的通用方法------printf只负责格式化,底层输出函数指向你的USART。改一个函数,printf就能活过来。调试效率提高10倍。写在最后,嵌入式调试,信息越详细,定位Bug越快。重定向printf到串口,让单片机"开口说话"。调试神器,学会就回不去。

(本文灵感源于于振南《新概念ARM32单片机》教程第4.7节"优化 USART 发送,用 printf 打印输出"。)

觉得有用?点赞、转发,让更多人学会"printf重定向"这个调试利器。

相关推荐
eng八戒2 小时前
【RA-Eco-RA2L1开发板评测】基于 FSP 实现串口打印功能
单片机·嵌入式硬件
嵌入式ZYXC2 小时前
第2篇:《面试题:LDO和DC-DC的区别?分别用在什么场景?》
stm32·单片机·嵌入式硬件·面试·职场和发展
HAPPY酷3 小时前
单片机OLED进阶:打造赛博朋克风“碎片化消散”文字特效
单片机·嵌入式硬件·microsoft
czhaii3 小时前
GB2312简体中文编码表
单片机·算法
玩转单片机与嵌入式3 小时前
AI 推理会不会堵住实时任务?MCU 上跑模型时,RTOS 和 DMA 该怎么配合?
人工智能·单片机·嵌入式硬件
清风6666663 小时前
基于单片机的超声波人体感应PWM自动调光灯设计与实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
fffzd3 小时前
STM32:IIC与温湿度传感器(轮询模式)
stm32·单片机·嵌入式硬件·iic·通信·嵌入式软件·i2c
项目題供诗3 小时前
STM32-编码器接口测速(十七)
stm32·单片机·嵌入式硬件
嵌入式小站3 小时前
STM32 零基础可移植教程 19:I2C 读写寄存器,先读一个设备 ID
stm32·单片机·嵌入式硬件