在单片机程序中,printf 并非绝对禁用,但频繁使用需谨慎。其核心代价是重定向到串口时,每个字符都需等待发送完成(阻塞式),在低波特率(如9600)下,一次 printf 可能耗时数毫秒,严重影响实时性。若必须使用,建议:1)仅在调试阶段使用,发布版本用宏开关(如 `#ifdef DEBUG`)裁剪;2)改用非阻塞的 DMA + 环形缓冲区实现 printf 重定向,或使用 `vsnprintf` 格式化到局部缓冲区后一次性发送;3)对于高频日志,改用二进制协议或直接写寄存器。实操中,我常用 `printf` 输出关键状态,但用 `sprintf` 到数组再通过中断发送,避免阻塞主循环。
```c
// 示例:重定向到DMA串口
int fputc(int ch, FILE *f) {
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, ch);
return ch;
}
```
记住:性能敏感路径(如中断服务函数)绝对禁用 printf,改用寄存器操作或标志位。
mcuku 阿沐 · 2026-08-18