| 很多 MCU 工程表面跑得挺好,一上线就出问题。原因通常不是硬件坏,而是代码里埋了“容易犯错”的地雷。本文整理了单片机开发中最常见的 Bug 类型、典型例子以及规避建议,适合裸机、RTOS 和各种嵌入式场景。 一、中断相关问题(最容易出 BUG) 中断和主程序共享变量未同步 
中断优先级错误 
中断未清标志 
 问题:ISR 中未清除中断标志,导致反复触发。建议: 
 判断中断源后第一时间清除标志;ISR 尾部不能依赖“自然清除”。 
 
 
 示例:void TIM2_IRQHandler(void) {
 if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
 {
 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 一定要先清标志
 // 处理中断事件...
 }
 }
 
 
 
 二、内存和指针问题 指针非法访问 / 越界 
 问题:数组越界、空指针解引用、类型错误。建议: 
 所有数组操作都加边界检查;禁止使用未经初始化的指针;用调试器查看访问地址是否合法。 
 
栈溢出 
 问题:局部变量太大、递归、ISR 堆栈深度太大。后果:程序跑飞或重启。建议: 
 减少 ISR 内局部变量;使用全局缓冲区替代大数组;注意链接文件栈空间配置。 
 
DMA 与 CPU 访问冲突 
 
 三、外设配置问题 四、状态机与逻辑控制 if/else 过多,流程混乱 
状态变量未初始化 
 问题:未初始化的状态进入未知分支。建议: 
 进入主循环前初始化所有状态变量;状态机中加入默认处理。 
 
 
 五、volatile 使用不当 六、时序问题 初始化顺序错误 
接口协议时序不满足(如 SPI/I2C) 
 问题:时钟/片选/延时配合不对,导致通信失败。建议: 
 
 
 七、看门狗相关 忘记喂狗 / 错误喂狗 
 问题:系统运行中被错误复位。建议: 
 喂狗应在主任务执行成功后再进行;不能在死循环或异常分支内喂狗。 
 
 
 八、编译优化与链接问题 DEBUG 能跑,RELEASE 崩溃 
ISR 名字拼错,启动文件未链接 
 后果:中断触发直接跑飞。建议: 
 检查启动文件中断向量表定义;建议使用统一 ISR 重定向表。 
 
 
 九、边界条件与偶发异常 缓冲区满、队列溢出、越界访问 
 问题:数据量超过处理能力未及时判断,导致错乱。建议: 
 加入队列满判断、缓冲区环绕判断;使用 assert 或日志记录关键边界。 
 
高负载时偶发问题 
 
 十、RTOS 混用错误(如使用 FreeRTOS) 总结:单片机开发中常见的高风险点汇总如下 【中断同步】    共享变量未保护【指针内存】    数组越界 / 栈溢出
 【外设配置】    GPIO、时钟、USART 时序错误
 【状态逻辑】    没有状态机、流程混乱
 【volatile】    缺失或误用
 【DMA冲突】     DMA 与 CPU 同时操作
 【看门狗】      忘记喂狗或错误喂狗
 【编译优化】    DEBUG 能跑,RELEASE 崩溃
 【RTOS】        中断中误用任务 API、优先级错误
 建议: 如有需要,我可以分享一份中断+缓冲+状态控制的高可靠通信模板(裸机/RTOS皆可)。 
 欢迎补充与交流。希望本文能帮你提前避免那些“我也不知道为啥炸了”的问题。 
 |