目录
[三、软件代码高频 Bug](#三、软件代码高频 Bug)
[四、通信类问题通用排查(串口 / I2C/SPI)](#四、通信类问题通用排查(串口 / I2C/SPI))
前言
前面三篇完成单片机硬件、外设、中断进阶理论学习。本篇聚焦实际开发调试,讲开发常用调试手段、高频 BUG、排错流程,很多新手写代码能编译,但板子跑不起来,大部分问题都可以用本章思路定位解决。
一、单片机常用调试手段
- 串口打印调试
- 最通用低成本调试方式,初始化 USART,把变量、状态打印到串口助手。
- 适合看变量数值、程序运行到哪一步、传感器读取数据。
- 缺点:占用串口资源,高速场景会影响时序。
- LED 指示灯调试
- 最简调试,用 LED 闪烁、不同闪烁频率判断程序运行状态。
- 例:正常运行 1s 闪烁一次;进入错误状态快闪。
- 适合没有调试器、板子资源紧张场景。
- 断点调试(ST‑LINK/J‑LINK)
- 硬件调试器,打断点,程序运行到断点直接停下。
- 可以单步执行、查看寄存器、看 RAM 变量、查看堆栈。
- 优势:可以看到程序内部真实状态,定位死循环、硬件异常。
- 注意:部分外设时序会被断点干扰,不能完全等同于真实运行。
- 逻辑分析仪
- 抓取 GPIO、I2C、SPI、USART 引脚真实电平波形。
- 专门排查通信类问题:通信不上、数据乱码、时序不对。
二、硬件层面常见问题
- 最小系统故障
- 现象:芯片完全不运行,下载程序失败。
- 排查:电源电压是否正常、复位电平、晶振是否起振、下载器接线。
- GPIO 驱动问题
- IO 输出没有反应:确认时钟开启、引脚模式配置,推挽 / 开漏选择错误。
- 按键读值不稳定:缺少上 / 下拉电阻,外部电平浮空。
- 电源噪声
- 现象:程序随机死机、外设乱跳。
- 排查:电源滤波电容是否焊接,电机继电器等干扰源隔离。
三、软件代码高频 Bug
数组越界 写超出数组长度的地址,破坏堆栈、全局变量,程序随机死机,无固定复现条件,最难排查。
中断函数写复杂逻辑 中断里面写延时、大循环、打印大量数据。后果:中断长时间占用,其他中断得不到响应,系统卡顿丢数据。
原则:中断只做标记赋值,业务逻辑放到 while (1) 主循环。
忘记开启外设时钟 STM32 所有外设时钟默认关闭,不开启时钟,外设完全失效,寄存器读写无效。新手最高频错误。
变量没有加 volatile 中断里面修改的全局变量不加 volatile,编译器优化,主循环读取不到更新后的值。
堆栈溢出 局部变量定义过大,函数嵌套太深,堆栈耗尽直接跑飞死机。
四、通信类问题通用排查(串口 / I2C/SPI)
- 确认硬件接线:SDA/SCK/MOSI 等引脚有没有接反。
- 参数严格匹配:波特率、时钟极性、从设备地址。
- 电平匹配:3.3V 单片机不要直接接 5V 器件,会烧坏芯片。
- 优先用逻辑分析仪看波形,区分是硬件问题还是代码问题。
五、通用排错流程(标准化排查步骤)
- 确认硬件:电源、接线、器件焊接是否没问题。
- 最小工程验证:写最简点灯程序,确认芯片本身可以正常运行。
- 分层定位:先硬件,再底层外设,再业务逻辑。
- 缩小范围:注释掉部分代码,定位哪一段代码导致异常。
- 借助工具:串口打印、断点、逻辑分析仪,不要只靠猜。
六、编译器与下载常见坑
- 编译成功不等于代码可以正常运行,编译只检查语法,不检查逻辑、硬件配置。
- 下载失败:下载器驱动、BOOT 引脚、复位电路、芯片选型选错。
- 烧录后程序不运行:下载完没有复位,或者 Flash 选项字节配置错误。
