上电后每隔约半秒复位一次,怎么确认是不是 IWDG?
IWDG 超时 = (4×2^PR×RLR)/LSI;PR=0、RLR=0xFFF、LSI≈32 kHz 时正好 512 ms。若 option byte 把 IWDG 设为硬件模式,软件关不掉,必须 main() 第一行写 0xAAAA,否则初始化稍长就被复位。
现象是「程序好像根本没跑起来」:串口只吐出半行、调试器停不住、复位反复发生,间隔大约半秒。先别改代码——算一下 IWDG 的超时:(4 × 2^PR × RLR) ÷ LSI。PR = 0、RLR = 0xFFF、LSI 按 32 kHz 计,结果是 0.512 秒。如果你的初始化流程超过 512 ms,芯片会在这个时间点被复位,表现出来就是「初始化没做完又重来」。
现象
三个特征同时出现时,先怀疑看门狗而不是业务代码:
| 观察 | 说明 |
|---|---|
| 复位周期性出现,间隔稳定在 0.5 秒量级 | 与代码执行路径无关,像被外部计时器打断 |
| 串口打印总是停在初始化某一行,且每次停的位置相近 | 初始化耗时超过超时时间 |
| 调试器里单步或长时间停在断点,芯片突然复位 | halt 不会停止独立看门狗 |
最容易误判的是第三条:断点上停下来思考一会儿,芯片自己重启了,看起来像「调试器坏了」。
原因
IWDG 由独立的 LSI 时钟驱动,与系统时钟、内核状态都无关。超时时间由三个量决定:
超时 = 4 × 2^PR × RLR ÷ LSI
代入 PR = 0(预分频 4)、RLR = 0xFFF(重装载 4095)、LSI = 32000 Hz:
4 × 1 × 4095 ÷ 32000 = 0.5119 s ≈ 512 ms
关键在于它是否被使能、以及由谁使能。IWDG 有两种启动方式:
- 软件模式:代码里显式启动,软件可以决定不启动。
- 硬件模式:由 option byte 选中,上电即自动启动,软件无法关闭。
option byte 是烧在芯片里的配置,可能因为批次、板厂烧录流程而不同。所以「这块板子上电就有看门狗」不能直接推广成「所有同型号芯片都这样」——判断依据应当是读回当前芯片的 option byte 状态,或者用复位间隔去反推。
另一个坑在配置顺序:IWDG 启动后,修改预分频(PR)与重装载(RLR)需要先写保护键,再等 PVU / RVU 标志清零。等待期间计数器仍在跑,如果此时剩下的计数值很小,芯片会在你配置到一半时复位。
怎么做
第一步:先确认,再改代码。 两条路,任选其一或都用。
方法 A(量时间):让固件在复位后第一行翻转一个 GPIO,
用示波器/逻辑分析仪量两次翻转的间隔。
间隔 ≈ 512 ms 且与代码路径无关 → IWDG 硬件模式已启用。
方法 B(读配置):读当前芯片的 option byte 状态寄存器
(STM32H7 在 FLASH_OPTSR 系列寄存器里),
看与 IWDG 软件/硬件模式相关的位。
具体位号按 RM0468 的 FLASH 章节核对,不要照抄别的系列。
第二步:把喂狗放在最前面,并且贯穿主循环。
#define IWDG_KR (*(volatile uint32_t *)0x58004800UL) /* H7: IWDG base + 0x00 */
int main(void) {
IWDG_KR = 0xAAAA; /* 第一行就喂:此时还没做任何初始化 */
clock_init(); /* 可能耗时较久的初始化 */
gpio_init();
isr_engine_init();
while (1) {
IWDG_KR = 0xAAAA; /* 主循环持续喂,避免长任务期间被复位 */
protocol_poll(); /* 不阻塞 */
}
}
0xAAAA 是「重装载」键,写进去会把计数器重置为 RLR 的值。三个常用键值:0xCCCC 启动、0xAAAA 喂狗、0x5555 解锁写保护。
第三步:不要顺手改 PR / RLR。 如果确实需要更长超时,务必在启动后立刻配置、并确认 PVU/RVU 已清零再继续;不要在初始化中途、计数值已经不多的时候去改。
验证
改前改后的判定标准只有一条:复位是否与初始化耗时解耦。
| 检查 | 改前 | 改后 |
|---|---|---|
| 复位间隔 | 稳定约 512 ms,与代码路径无关 | 不再周期性复位 |
| 初始化是否能跑完 | 停在中途同一位置 | 完整执行到主循环 |
| 主循环计数(RTT 上报的样本数) | 停在接近 0 | 持续单调增长 |
补充一个交叉验证:把 RLR 改成另一个值(例如 0x7FF),超时应变成约 256 ms。若复位间隔随 RLR 成比例变化,基本可以确定是 IWDG;若间隔不变,则要转向电源、时钟锁定失败、HardFault 循环等方向排查。

边界
- option byte 的出厂配置因芯片、批次、板厂烧录流程而异,本文的 512 ms 是「PR=0、RLR=0xFFF、LSI=32 kHz」这一组配置下的计算值,不是所有 H7 板子的默认行为。
- LSI 精度有限(随温度与电压漂移),因此 IWDG 只能做「防死锁」用途,不能当精确定时器使用;需要准确超时请用 LSI 校准或改用外部时钟驱动的定时器。
- IWDG 启动后无法关闭(硬件模式下更是如此),调试长时间停在断点时会被复位;需要长断点调试时应在调试构建里避免启用硬件看门狗,或缩短单次停留时间。
- 不同系列的寄存器位置与 option byte 名称不同(F1 用 IWDG_SW 位,H7 在 FLASH_OPTSR 系列里),跨系列不能照搬位号。
- 若复位间隔既不是 512 ms 也不随 RLR 变化,本方法不适用,应检查供电跌落与时钟启动失败。
最后验证于 2026-10-29 · STM32H723ZG(RM0468)· LSI 按 32 kHz 计算