看门狗
STM32 独立看门狗 IWDG 与窗口看门狗 WWDG
STM32 中常见的两种看门狗:
- IWDG(Independent Watchdog)独立看门狗
- WWDG(Window Watchdog)窗口看门狗
两者的核心目的都是:
当程序异常、死循环、跑飞或者长时间没有正常运行时,自动复位 MCU,让系统恢复运行。
但两者最大的区别是:
IWDG:只要求“不能太晚喂狗”
WWDG:要求“不能太早,也不能太晚喂狗”一、独立看门狗 IWDG
IWDG 使用独立的 LSI(Low Speed Internal)低速内部时钟。
因此它与系统使用的 HSE、PLL、HCLK 等时钟相对独立。
LSI
↓
IWDG
↓
倒计时
↓
程序正常 → 定期喂狗 → 重新计时
程序异常 → 无法喂狗 → 计数到0 → MCU复位这也是 IWDG 很适合用于:
系统死机保护、程序跑飞保护。
二、IWDG 的 CubeMX 配置
在 CubeMX 中:
IWDG
↓
Enable例如配置:
Prescaler = 64
Reload = 1000具体的超时时间需要根据 STM32 对应型号的 LSI 频率以及 IWDG 分频规则计算。
三、IWDG 初始化代码
CubeMX 生成的 HAL 代码一般类似:
IWDG_HandleTypeDef hiwdg;
static void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
hiwdg.Init.Reload = 1000;
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
{
Error_Handler();
}
}这里两个参数最重要:
hiwdg.Init.Prescaler负责对 LSI 时钟进行分频。
例如:
LSI
↓
÷64
↓
IWDG 计数时钟而:
hiwdg.Init.Reload表示看门狗计数器的重装值。
四、IWDG 喂狗
IWDG 启动以后,程序必须在规定时间内刷新计数器。
while (1)
{
/* 用户程序 */
HAL_IWDG_Refresh(&hiwdg);
}HAL_IWDG_Refresh() 的作用就是:
重新加载 IWDG 计数器,使它重新开始倒计时。
正常运行时:
程序正常运行
↓
Refresh
↓
重新计数
↓
Refresh
↓
重新计数
↓
……如果程序死机:
程序死机
↓
无法执行 Refresh
↓
IWDG继续计数
↓
计数到0
↓
MCU复位五、窗口看门狗 WWDG
WWDG 与 IWDG 最大的区别就在于:
WWDG 具有“窗口”的概念。
它不仅要求:
不能太晚喂狗。
还要求:
不能太早喂狗。
可以理解成:
太早 正常窗口 太晚
↓ ↓ ↓
──────────┬──────────────────┬──────────────────┬──────
× √ ×因此 WWDG 可以同时检测:
① 程序长时间不喂狗
② 程序跑飞后疯狂喂狗六、WWDG 的 CubeMX 配置
在 CubeMX:
WWDG
↓
Enable例如:
Prescaler = 8
Window = 80
Counter = 127具体参数范围和计数时间需要按照具体 STM32 型号的参考手册确认。
七、WWDG 初始化代码
HAL 代码一般类似:
WWDG_HandleTypeDef hwwdg;
static void MX_WWDG_Init(void)
{
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
hwwdg.Init.Window = 80;
hwwdg.Init.Counter = 127;
if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
{
Error_Handler();
}
}其中:
Counter可以理解为:
当前看门狗计数器的初始值。
而:
Window决定:
什么时候开始进入允许刷新看门狗的时间窗口。
八、WWDG 的工作过程
假设:
Counter = 127
Window = 80计数器不断递减:
127
↓
126
↓
125
↓
...
↓
81
↓
80 ← 到达窗口
↓
79
↓
78
↓
...
↓
0通常只有进入允许的窗口后,程序才能执行刷新。
所以:
Counter > Window
↓
太早
↓
不能刷新进入窗口后:
Counter <= Window
↓
允许刷新如果一直不刷新:
Counter → 0
↓
复位因此:
太早喂狗 → 异常
正常窗口喂狗 → 正常
太晚不喂狗 → 复位九、WWDG 喂狗
HAL 中刷新 WWDG:
HAL_WWDG_Refresh(&hwwdg);例如:
while (1)
{
/* 用户程序 */
HAL_WWDG_Refresh(&hwwdg);
}但这里不能像 IWDG 一样“想什么时候 Refresh 就什么时候 Refresh”。
必须让程序在规定的时间窗口内执行。
十、IWDG 和 WWDG 的核心区别
| 项目 | IWDG | WWDG |
|---|---|---|
| 全称 | Independent Watchdog | Window Watchdog |
| 时钟 | LSI | PCLK1 |
| 与系统主时钟是否独立 | 相对独立 | 依赖系统时钟 |
| 是否有喂狗窗口 | 无 | 有 |
| 太晚喂狗 | 复位 | 复位 |
| 太早喂狗 | 一般不会因此复位 | 会触发异常 |
| 配置难度 | 简单 | 相对复杂 |
| 常见用途 | 程序死机保护 | 更严格的软件执行异常检测 |
可以简单记忆:
IWDG:
能喂就行
↓
不能太晚
WWDG:
有规定时间
↓
不能太早
也不能太晚十一、为什么 WWDG 能检测“疯狂喂狗”?
假设程序正常:
程序运行
↓
等待
↓
进入允许窗口
↓
喂狗
↓
重新计数但是程序如果跑飞到了某个循环:
while (1)
{
HAL_WWDG_Refresh(&hwwdg);
}那么程序可能会非常频繁地执行刷新。
如果此时计数器还没进入允许窗口:
疯狂 Refresh
↓
太早
↓
违反 WWDG 窗口条件
↓
检测到异常这就是 WWDG 与 IWDG 很重要的区别。
十二、两种看门狗的典型使用场景
IWDG:系统死机保护
例如 FreeRTOS 系统:
任务正常运行
↓
系统周期性喂狗
↓
程序正常工作如果出现:
死循环
任务卡死
程序跑飞
系统异常导致长时间不能喂狗:
IWDG超时
↓
MCU复位IWDG 的优点是简单,而且使用独立的低速时钟,比较适合做系统最后一道保护。
WWDG:严格执行节奏检查
WWDG 更适合对程序执行时间有明确约束的场景。
例如规定:
某个控制流程必须在规定时间段执行那么:
执行太快
↓
可能说明程序跑飞
执行太慢
↓
可能说明程序卡死WWDG 的窗口机制就可以同时约束这两个方向。
十三、实际工程中不要直接在 while(1) 里无脑喂狗
例如:
while (1)
{
Task1();
Task2();
Task3();
HAL_IWDG_Refresh(&hiwdg);
}这种写法虽然简单,但并不能真正证明:
Task1正常
Task2正常
Task3正常因为可能:
Task2死循环但程序根本走不到:
HAL_IWDG_Refresh();这是好的。
但如果某个任务异常之后仍然能够执行到喂狗代码,那么看门狗可能不会触发。
在 FreeRTOS 中,更可靠的方式通常是:
各个关键任务
↓
周期性报告“我还活着”
↓
统一监控机制确认所有任务正常
↓
确认正常后才喂狗这样看门狗监控的就不仅仅是:
CPU 有没有运行。
而是:
系统中的关键任务是不是都还正常运行。
十四、最核心的代码
IWDG
初始化:
static void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
hiwdg.Init.Reload = 1000;
HAL_IWDG_Init(&hiwdg);
}喂狗:
HAL_IWDG_Refresh(&hiwdg);核心:
超时不喂 → MCU复位WWDG
初始化:
static void MX_WWDG_Init(void)
{
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
hwwdg.Init.Window = 80;
hwwdg.Init.Counter = 127;
HAL_WWDG_Init(&hwwdg);
}喂狗:
HAL_WWDG_Refresh(&hwwdg);核心:
太早喂 → 异常
正常窗口喂 → 正常
太晚不喂 → 复位十五、最终总结
看门狗的本质就是:
给程序设置一个“必须定期证明自己还活着”的机制。
IWDG:
超过规定时间没有喂狗
↓
复位WWDG:
太早喂
↓
异常
正常窗口喂
↓
正常运行
太晚不喂
↓
复位因此:
IWDG = 超时保护
WWDG = 窗口 + 超时保护对于一般 STM32 系统,IWDG 是更常见、更简单的系统异常复位手段;WWDG 则适合需要额外约束程序执行时序的场景。具体预分频、计数周期和窗口边界应以目标 STM32 型号的参考手册和 CubeMX 生成配置为准。
独立看门狗









初始化函数



喂狗函数
窗口寄存器(了解,独立看门狗很少用)

实战思路

窗口看门狗和其区别

以下是 窗口看门狗(WWDG) 和 独立看门狗(IWDG) 的区别,以表格形式呈现:
| 特性 | 窗口看门狗(WWDG) | 独立看门狗(IWDG) |
|---|---|---|
| 时钟源 | APB1 时钟(与系统时钟相关) | 独立于系统时钟的低速内部时钟(LSI,通常为 32kHz) |
| 工作模式 | 提供窗口机制:必须在规定时间窗口内喂狗,否则会触发复位 | 没有窗口限制,只需在计数器溢出前喂狗即可 |
| 计时范围 | 时间窗口限制计时(如 5ms 到 20ms) | 可配置更长的超时时间范围(取决于 LSI 分频器设置) |
| 复位控制 | 可通过 APB 时钟停止时暂停 | 无法停止,即使 MCU 进入低功耗模式仍然运行 |
| 初始化复杂性 | 需要设置窗口大小和刷新计时窗口 | 初始化简单,只需设置超时时间和启用 |
| 优先应用场景 | 高实时性场景,限制喂狗时间窗口,用于更精准的监控 | 更注重系统稳定性,在任意时间内确保系统无死机 |
| 可靠性 | 依赖系统时钟,可能受到系统配置或时钟故障影响 | 独立于系统时钟,运行更可靠 |
| 电源模式支持 | 系统时钟关闭时无法运行 | 即使进入低功耗模式(如停止模式),也可正常运行 |
| 应用复杂度 | 需要额外的窗口时间管理,配置相对复杂 | 使用简单,只需定时喂狗 |
| 典型应用 | 实时性强的场景,防止过早或过晚喂狗(如工业设备) | 通用场景,确保系统在任意情况下都能重启(如安全设备) |
总结
- 窗口看门狗(WWDG) 更适合需要严格控制喂狗时间的高实时性场景,但依赖系统时钟,不适合完全独立的监控。
- 独立看门狗(IWDG) 更可靠,适合需要系统始终受到监控的场景(如关键安全设备),即使 MCU 进入低功耗模式也能运行。
根据实际需求选择适合的看门狗类型!
窗口看门狗原理

用户设置一个窗口区间,计数器值大于区间上限的话,这时喂狗会产生复位,在区间内喂狗不会产生复位(只能在区间喂狗),到了区间下限还没有喂狗则触发复位
任务看门狗
软件层和硬件层相互协作,软件触发时间小于硬件,在硬件跑飞的前一段时间触发遗言

