当前位置: 首页 > news >正文

STM32 printf 串口重定向代码完整解析

STM32 printf串口重定向代码完整解析

一、先提取图片完整代码

#include"usart.h"/* USER CODE BEGIN 0 */intfputc(intch,FILE*f){/* 发送一个字节数据到串口DEBUG_USART */HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1000);return(ch);}/* USER CODE END 0 */

二、核心概念:什么是串口重定向?

1. 标准C库默认行为

C语言标准函数printf()putchar()底层依赖标准库函数fputc,默认是向**电脑屏幕(标准输出stdout)**输出字符。
但单片机没有屏幕,直接调用printf会报错、无任何输出。

2. 重定向本质

重写fputc函数,把原本输出到屏幕的字符,拦截下来,改用串口(USART1)发送出去。
之后你在代码里直接写printf("hello\r\n");,字符串就会通过串口1发送到电脑串口助手,实现打印调试。

三、逐行拆解代码逻辑

  1. int fputc(int ch, FILE *f)

    • fputc:标准库单字符输出底层接口,printf循环调用它逐个输出字符
    • ch:要输出的单个字符(ASCII码,int类型兼容扩展字符)
    • FILE *f:文件指针,printf默认传入标准输出stdout,这里我们不需要用到,仅占位
  2. HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
    HAL库阻塞式串口发送函数,参数含义:

    • &huart1:串口1句柄(CubeMX生成,对应硬件USART1)
    • (uint8_t *)&ch:取字符ch的地址,强转为字节指针,供函数读取1字节数据
    • 1:本次只发送1个字节
    • 1000:发送超时时间1000ms,超时直接退出
  3. return (ch);
    标准规范:发送成功后返回原字符,兼容标准库逻辑,不能省略。

四、使用前提(必须满足,否则报错)

  1. CubeMX已配置USART1,生成huart1全局句柄,并且正确初始化串口;
  2. 工程需要勾选Use MicroLIB(Keil MDK),否则标准库FILE接口缺失,重定向失效;
  3. 头文件依赖:需要包含<stdio.h>,否则FILEprintf未定义;
  4. 硬件:USART1 TX/RX引脚接USB转串口模块,连接电脑串口助手。

五、完整使用示例

#include"stdio.h"// 必须加,printf、FILE定义在这里#include"usart.h"/* USER CODE BEGIN 0 */intfputc(intch,FILE*f){HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1000);returnch;}/* USER CODE END 0 */intmain(void){HAL_Init();SystemClock_Config();MX_USART1_UART_Init();while(1){// 直接使用printf,自动走串口1输出printf("当前循环运行中\r\n");HAL_Delay(1000);}}

六、优缺点 & 补充注意

优点

  • 不用手动调用HAL_UART_Transmit拼接字符串,直接用熟悉的printf格式化打印;
  • 支持%d %s %f等格式化输出,调试更方便。

缺点

  1. HAL_UART_Transmit阻塞发送:串口发送时CPU卡死等待,大量打印会拖慢程序运行;
  2. 只能单向发送,若需要scanf串口接收,还要重写fgetc函数;
  3. 不加MicroLIB会出现内存溢出、程序卡死。

优化拓展(非阻塞版本)

如果担心阻塞,可以改用中断/DMA发送,替换HAL_UART_Transmit

// 非阻塞版本,不占用CPUHAL_UART_Transmit_IT(&huart1,(uint8_t*)&ch,1);while(HAL_UART_GetState(&huart1)==HAL_UART_STATE_BUSY_TX);

七、一句话总结

这段代码是STM32 HAL库的printf串口重定向模板:通过重写标准库底层输出函数fputc,把printf打印内容转发到硬件串口1,实现单片机向电脑串口助手打印调试信息。

http://www.gsyq.cn/news/1618030.html

相关文章:

  • AI 效率工具产品化:从功能清单到 PMF 验证闭环
  • Vue3 全栈应用架构:组合式 API 不是把逻辑随便抽走
  • Go 并发编程:生产服务里 goroutine 要有退出路径
  • 机器人(狗)、AGV/AMR自动乘梯简易方案(技术解析与补充
  • 字节豆包AI编程助手扩展:深度解析其代码能力边界与实战表现
  • 极简架构设计:少一层抽象,少一类故障
  • 什么是数字工厂全要素智造中枢与适用于哪种企业
  • LeetCode 23.合并K个升序链表
  • Visa、Stripe等140余家机构联合推出Open USD稳定币,剑指Tether
  • HBM Predictor安装与配置教程:简单5步搭建预测环境
  • 年入100亿压缩机龙头IPO!1.66亿诉讼案未决,应收账款质量恶化
  • ChatGPT Plus / Pro 付款后没看到结果,先查这几步
  • 番茄小说下载器终极指南:三分钟打造个人离线图书馆的完整教程
  • 单帧像素推演三维空间,SpaceOS联动Pixel2Geo打通单画面实景重建全链路
  • YOLOv11 改进 - C2PSA C2PSA融合EDFFN高效判别频域前馈网络(CVPR 2025):频域筛选机制增强细节感知,优化复杂场景目标检测
  • 软件设计周期
  • 孩子确诊自闭症/多动症后该找谁?一份给迷茫家长的专业参考指南
  • M4Markets的长期使用感受顺不顺手?
  • 卡梅德生物科普:CD70(TNFSF7)的免疫共刺激机制与研究应用
  • 功能极简取舍:每个按钮都要为用户承担重量
  • Kiran-shell 显示桌面插件:一键隐藏所有窗口的底层机制
  • CPP 学习笔记 语法总结
  • 第91题 2026年国家级科研痛点:高压IGBT芯片场截止(FS)结构与背面减薄工艺
  • 选芯片编程烧录座,这3个专业性价比最稳
  • 直流电机静音控制方案:从PWM优化到PCB布局
  • SQL 复杂查询优化:先减少扫描,再谈语法漂亮
  • 6. 深入 Nginx 核心:HTTP 11 个处理阶段与模块开发实战
  • 【2026年华为暑期实习(AI)-7月1日-第三题- Certainty Forcing 训练损失计算】(题目+思路+JavaC++Python解析+在线测试)
  • AI 辅助:前端工程化效率:快不是少检查,而是少返工
  • 深度学习Pipeline与Baseline构建指南