【无标题】STM32 串口 Printf 重定向|标准库 + HAL库 两套极简通用代码(无需MicroLIB)

一、前言:为什么你的 printf 经常报错?

新手最常见问题:

  • 重定向代码不全,必须勾选 MicroLIB 才能编译
  • 打印偶尔卡死、串口乱码、重启
  • 标准库代码放到 HAL 工程报错、函数不兼容
  • 只能打印数字,无法打印字符串、中文
    核心原因:缺少半主机模式关闭代码、底层输出函数不匹配、超时参数错误。
    本文提供 纯原创、最精简、可量产 的两套重定向模板:
    ✅ 标准库版(STM32F1/F4 标准库工程通用)
    ✅ HAL库版(CubeMX 生成工程通用)
    无需任何库配置、无需勾选 MicroLIB、零冗余、直接复制即用。

二、原理一句话看懂

C 库的 printf 底层依赖 fputc 输出单个字符。

我们重写 fputc 函数,把原本输出到电脑屏幕的数据,转发到串口 USART。

同时关闭 ARM 半主机调试模式,避免工程必须依赖 MicroLIB。


三、STM32 标准库|极简 printf 重定向(推荐量产)

适用:所有标准库工程、Keil 环境、无需 MicroLIB

使用串口:USART1,可自行修改

#include "stdio.h"

#include "stm32f10x_usart.h"

//关闭半主机模式,彻底摆脱MicroLIB

#pragma import(__use_no_semihosting)

//兼容库函数,防止编译报错

void _sys_exit(int x)

{

x = x;

}

//printf底层重定向函数

int fputc(int ch, FILE *f)

{

USART_SendData(USART1, (uint8_t)ch);

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

return ch;

}

优势:

  • 代码最短、执行最快、无阻塞延时
  • 支持字符串、数字、小数、中文打印
  • 工程稳定,量产项目首选

四、STM32 HAL库|极简 printf 重定向(CubeMX 专用)

适用:CubeMX 生成的所有 HAL 工程、F1/F4/H7 全系列

无需修改任何配置,直接放在 usart.c 文件末尾

#include "stdio.h"

extern UART_HandleTypeDef huart1;

#pragma import(__use_no_semihosting)

void _sys_exit(int x)

{

x = x;

}

//HAL库 printf 重定向

int fputc(int ch, FILE *f)

{

HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);

return ch;

}

如果你的串口是 USART2,只需修改 &huart2 即可。


五、最简测试代码(直接验证)

int main(void)

{

USART_Init(); //标准库初始化

//MX_USART1_UART_Init(); //HAL库初始化

复制代码
while(1)
{
    printf("Volt:%.2f\r\n",3.14f);
    printf("Status:OK\r\n");
    HAL_Delay(500);
}

}

六、工程必须注意的 5 个关键点(避坑)

1、彻底不用 MicroLIB

很多旧教程必须勾选 MicroLIB,本文代码完全不需要,避免库冲突、内存占用变大。

2、中文乱码解决

工程编码改为 UTF-8,串口助手编码同样选择 UTF-8,中文完美打印。

3、不要在中断里疯狂 printf

串口发送是轮询阻塞模式,中断高频打印会导致系统卡死、堆栈溢出。

4、必须先初始化串口,再调用 printf

顺序错误会直接串口失效、程序卡死。

5、多串口打印修改句柄即可

需要 USART2 打印,仅需把 huart1 改为 huart2,无需改其他逻辑。


七、常见报错快速解决

报错1:undefined reference to `_sys_exit'

缺少 _sys_exit 函数,复制本文完整代码即可解决。

报错2:printf 无输出、黑屏

串口未初始化、波特率不匹配、重定向句柄和实际串口不一致。

报错3:偶尔卡死

中断内调用 printf、高频率打印阻塞主线程。


八、总结(工程规范)

  1. printf 重定向核心就是重写 fputc + 关闭半主机模式;
  2. 标准库、HAL库两套代码完全独立,按需复制,零修改即可用;
  3. 不开启 MicroLIB 是现代嵌入式工程最佳规范;
  4. 串口打印仅用于调试,禁止业务逻辑高频依赖 printf。
相关推荐
不悔哥1 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
XiHongShi20161 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
优信电子1 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
深圳老胡1 天前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
wuyk5551 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
女神下凡1 天前
嵌入式设计的各种存储芯片的硬件/软件设计规范,非常全面。
arm开发·单片机·嵌入式硬件
梅梅9661 天前
一款mipi转lvds的lcd调试(LT8912B)
单片机·计算机外设·电脑·显示器·pd芯片
开发笔记-阿牛1 天前
蓝牙音乐灯拆解,又一次拆到蓝牙音乐灯芯片CK6865L
人工智能·单片机·嵌入式硬件·音视频·音频
从零开始的嵌入式之旅1 天前
day47
arm开发·经验分享·笔记·嵌入式硬件
恒锐丰科技林技术员1 天前
EG1164 高压大电流升压同步整流芯片解析
经验分享·嵌入式硬件·硬件工程