这一章在干嘛? 窗口门狗 WWDG 实验:APB1 时钟、7 位递减计数器、上窗口限制。比 IWDG 更严格,适合「主循环跑完一圈」必须在指定时间内的场景。
19.1 WWDG 简介
WWDG(Window Watchdog)= 窗口看门狗。
- 时钟源:PCLK1(42 MHz)4096 分频 → 约 10 kHz;
- 计数器:7 位递减(0x40~0x7F);
- 窗口:T[6:0] 必须 > 窗口值 W[6:0] 才能喂狗;
- 行为:计数到 0x40 → 复位;计数到 0x3F → 立即复位。
原书图 19.1.1:WWDG 时序图
核心公式:
[[formula|超时时间 Tout = (4096 × 2^WDGTB × (T[5:0]+1)) / PCLK1]]
| WDGTB | 分频 | 最大超时 |
| 0 | /1 | ~4.1 ms |
| 1 | /2 | ~8.2 ms |
| 2 | /4 | ~16.4 ms |
| 3 | /8 | ~32.8 ms |
T[6:0] 是计数器设置值,必须 0x40~0x7F 之间(最高位 T6 强制为 1 表示使能)。
窗口的意义:如果程序跑得太快(提前喂狗)也复位——这能检测到「程序死循环但又刷新了看门狗」的 bug。
19.2 硬件设计
无外部电路。
19.3 程序设计
19.3.1 编程步骤
HAL_WWDG_Init(&hwwdg); 配置 Prescaler / Window / Counter;HAL_NVIC_EnableIRQ(WWDG_IRQn); 开启中断(可选,用于早期唤醒);HAL_WWDG_Refresh(&hwwdg); 喂狗。
19.3.2 关键代码
WWDG_HandleTypeDef hwwdg;
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8;
hwwdg.Init.Window = 0x5F;
hwwdg.Init.Counter = 0x7F;
HAL_WWDG_Init(&hwwdg);
main:
while (1) {
delay_ms(20);
HAL_WWDG_Refresh(&hwwdg);
}
原书图 19.3.2.1:WWDG 喂狗时序图
中断里别忘了喂狗:Early Wakeup 中断会在计数器到 0x40 时触发,必须在这里喂狗或做应急处理。
19.4 下载验证
正常喂狗 → LED 闪烁;喂狗过早(delay 太小)→ 提前复位;喂狗过晚 → 超时复位。
原书图 19.4.1:WWDG 提前/延迟喂狗实验现象
原书图 19.4.2:WWDG 触发早期唤醒中断回调
🧠 小测验WWDG 的窗口含义?
计数器值必须大于窗口值时才能喂狗,否则复位。
WWDG 比 IWDG 严格在哪?
必须「准时」喂狗,太早太晚都复位;且能触发 Early Wakeup 中断。
如何配置 32 ms 超时、窗口 30 ms?
Prescaler=8,Counter=0x7F,Window=0x5F。