上电后每隔约半秒复位一次,怎么确认是不是 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 循环等方向排查。

时间线:512 ms 看门狗超时与 600 ms 初始化

边界

  • 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 计算

上电后每隔约半秒复位一次,怎么确认是不是 IWDG?

作者 JimmyZ,嵌入式 / 确定性控制方向。GitHub · 掘金