摘要:芯片上电,电源正常,晶振起振,但程序就是不跑?不是 Flash 坏了,而是BOOT0 引脚电平错误 或Option Bytes(选项字节) 被意外修改。本文解析 MCU 从“上电”到“取第一条指令”的硬件级筛选机制。
一、问题描述(现象)
**新焊接的 PCB,上电后无任何反应;
用示波器看晶振,有波形;
用调试器连,能连上,但程序跑不起来,或者跑几步就飞。**
很多工程师的排查方向是:
晶振没起振?
Flash 擦除不干净?
换一颗芯片试试?
二、原理分析
1. 物理模型
Cortex-M 上电后的硬件自检流程:
Power On -> POR (Power On Reset) -> 检查 BOOT0 引脚电平 -> 选择启动介质 (Flash / System Memory / SRAM) -> 读取 MSP 和 Reset Handler -> 执行代码2. 核心参数
BOOT0 / BOOT1:启动模式选择引脚。
Option Bytes (OB):存储在 Flash 中的特殊配置字(写保护、读保护、NRST 模式等)。
System Memory:系统存储区(通常存放 Bootloader)。
3. 反直觉真相
“BOOT0 悬空”等于“随机启动”。
如果 BOOT0 引脚没有下拉电阻:
上电瞬间,引脚电平可能是高,也可能是低。
结果是:有时进 Flash,有时进 System Memory,有时直接死机。
Option Bytes 写错:
开启了RDP(读保护)Level 2,芯片永久锁死。
开启了NRST_MODE,复位引脚变成了 GPIO,导致无法复位。
三、工程级解决方案
方案 1:BOOT0 必须“钉死”(硬件铁律)
永远不要悬空 BOOT0。
需求 | BOOT0 接法 |
|---|---|
正常从 Flash 启动 | 10kΩ 下拉到 GND |
需要 ISP 升级 | 按键上拉到 VDD(平时下拉) |
从 SRAM 启动 | 强制上拉到 VDD |
方案 2:Option Bytes 的“出厂默认值”
在量产烧录脚本中,必须包含 Option Bytes 的配置。
STM32 示例(STM32CubeProgrammer 命令):
# 解锁 Option Bytes -c port=SWD mode=UR -ob UNLOCK # 设置读保护为 Level 0(无保护) -c port=SWD mode=UR -ob RDP=0xAA # 设置 NRST 为复位引脚 -c port=SWD mode=UR -ob nRST_STOP=1 nRST_STDBY=1 # 锁定 Option Bytes -c port=SWD mode=UR -ob LOCK方案 3:无法连接调试器?
如果芯片因为 Option Bytes 锁死无法连接:
将BOOT0 拉高(进 System Memory)。
使用ISP 工具(如 FlyMcu、STM32CubeProgrammer)连接。
执行Full Chip Erase。
恢复 Option Bytes 默认值。
四、选型避坑建议
NRST 引脚:
尽量不要用作 GPIO,除非你非常清楚后果。
读保护(RDP):
Level 1:可以升级,不能读出。
Level 2:不可逆,一旦写入,芯片变砖。
写保护(WRP):
保护 Flash 某块区域不被擦写,误操作会导致升级失败。
五、总结 Checklist
[ ] BOOT0 引脚是否有 10kΩ 下拉电阻?
[ ] 量产烧录脚本是否包含了 Option Bytes 的初始化?
[ ] 是否误开启了 RDP Level 2?
[ ] NRST 引脚是否被配置成了 GPIO?
六、写在最后(关注我,少走弯路)
我是 gqqsherry,一个拒绝调包、专注底层逻辑的嵌入式工程师。
BOOT 配置是“一票否决制”,配置错了,再好的代码也跑不起来。
关注我的专栏《嵌入式底层避坑指南》,下一篇我们将深入解析《看门狗复位和软件复位有什么区别?别只怪喂狗,看看复位标志位》。
👉下一篇预告:《看门狗复位和软件复位有什么区别?别只怪喂狗,看看复位标志位》
原创文章,转载请注明出处。