ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

16.WDG看门狗

16.WDG看门狗 WDG简介看门狗的作用防死机机制单片机在复杂环境中如受电磁干扰可能会“跑飞”或“死机”。看门狗是一个硬件倒计时器程序在正常运行时必须定时去“喂狗”重置计数器。如果程序死机了来不及喂狗倒计时归零后看门狗就会强制让单片机复位重启。STM32的两种看门狗的区别独立看门狗IWDG使用的是内部的低速时钟LSI即使主时钟坏了它依然能工作。它只要求在一个时间内喂狗即可不能喂太晚安全性高适合用来防止程序彻底死锁。窗口看门狗WWDG使用的是主时钟PCLK1。它有“喂狗窗口”的限制既不能喂得太晚也不能喂得太早。如果程序跑飞了疯狂乱喂狗提前喂狗也会触发复位。它适合对时间精度要求极高、需要监控程序精确执行周期的场景比如要求必须在某段时间内完成任务。IWDG框图STM32独立看门狗IWDG的内部硬件框图。1.8V供电区寄存器配置部分IWDG_PR预分频寄存器用来设置8位预分频器的分频系数范围0-7对应4~256分频。由于LSI是40kHz通过分频可以控制计数器的递减速度。IWDG_RLR重装载寄存器存放12位的重装载数值最大4095。这是计数器的初始值。IWDG_KR键寄存器非常关键的寄存器写入特定值触发特定动作写入0xCCCC启动看门狗。写入0xAAAA执行“喂狗”看图中的箭头它把RLR的值重新加载给递减计数器。写入0x5555解除PR和RLR的写保护。IWDG_SR状态寄存器用来指示预分频器和重装载值的更新是否完成因为时钟不同步写入需要时间同步。VDD供电区核心逻辑电路LSI40kHz内部低速时钟这是独立看门狗的时钟源。因为它独立于主时钟即使主时钟坏了它也能工作这就是它叫“独立”看门狗的原因。8位预分频器接收LSI时钟根据PR寄存器的配置进行降频。12位递减计数器核心定时器。在时钟驱动下不断递减。如果减到0就会向右产生IWDG复位信号强制单片机重启。工作流程总结启动配置好PR和RLR后往KR写入0xCCCC计数器开始从RLR的值往下减。正常喂狗程序正常运行时定时往KR写入0xAAAA计数器会重新加载RLR的值归位不会触发复位。发生故障如果程序跑飞没能按时喂狗12位递减计数器一路减到0触发系统复位。IWDG键寄存器1. 键寄存器的本质与设计初衷本质它本质上是一个控制寄存器用于控制看门狗硬件电路的工作。设计原因防干扰普通的控制寄存器通常是“写1位”来控制某个功能。但在存在电磁干扰等恶劣环境下1个位很容易被意外翻转。因此STM32采用了“写入整个寄存器特定值Magic Number”的方式来代替单个位的操作极大地降低了硬件受到干扰而误动作的概率。2. 键寄存器写入值对照表写入IWDG_KR的值作用0xCCCC启用独立看门狗0xAAAA将 IWDG_RLR 中的值重新加载到计数器喂狗0x5555解除 IWDG_PR 和 IWDG_RLR 的写保护0x5555之外的其他值启用 IWDG_PR 和 IWDG_RLR 的写保护实际操作流结合前两张图在实际写代码时这几张图的知识是串联起来的标准配置流程如下解除保护先往IWDG_KR写入0x5555允许我们修改预分频PR和重装载值RLR。配置参数配置好IWDG_PR决定时钟分频和IWDG_RLR决定超时时间。启用看门狗往IWDG_KR写入0xCCCC看门狗开始跑。定时喂狗在程序正常运行的主循环或定时器中断里定期往IWDG_KR写入0xAAAA硬件会自动把 RLR 的值重载进 12位递减计数器防止它归零复位。重点注意事项为什么操作完IWDG_PR和IWDG_RLR后只要写入其他任意值就会再次锁定这是为了防止跑飞的程序意外修改了超时时间。一旦参数配置完毕并启动看门狗这两个寄存器就会被锁死保证看门狗的安全防线坚不可摧。如果需要重新配置只能先写入0x5555再次解锁。IWDG超时时间1. 核心公式超时时间TIWDGTLSI×PR预分频系数×(RL1)其中TLSI1/FLSI即LSI时钟的周期2. 看门狗超时时间参考表假设输入时钟 FLSI40k根据不同的预分频系数PR和重装载值RL计算得出的时间范围预分频系数PR[2:0]位最短时间(ms)(RL 0x000)最长时间(ms)(RL 0xFFF)/400.1409.6/810.2819.2/1620.41638.4/3230.83276.8/6441.66553.6/12853.213107.2/2566或76.426214.4深度解析与计算验证1. 公式参数拆解TLSI上一张图提到LSI是40kHz所以 TLSI1/400000.000025 秒 0.025 毫秒 (ms)。PR预分频系数由IWDG_PR寄存器配置对应表格中的 /4 到 /256。(RL1)IWDG_RLR中存放的是12位重装载值 RL范围0~4095。因为计数器减到0会触发复位所以实际计数的时钟节拍是 RL1 次。2. 表格数据验证以第一行为例最短时间RL0x000即RL00.025ms×4×(01)0.1ms最长时间RL0xFFF即RL40950.025ms×4×(40951)0.025×4×4096409.6ms0.025ms×4×(40951)0.025×4×4096409.6ms与表格相符绝对最大超时时间分频/2560.025ms×256×409626214.4ms0.025ms×256×409626214.4ms约26.2秒WWDG框图STM32窗口看门狗WWDG的内部硬件框图。时钟源PCLK1不同于IWDG使用独立的40kHz LSI时钟WWDG的时钟来源于PCLK1来自RCC时钟控制器即APB1总线时钟。这意味着WWDG的计数频率与系统主频挂钩。看门狗预分频器WDGTB用于对PCLK1进行分频从而调整计数器的递减速度。看门狗控制寄存器WWDG_CR如图下方所示它包含6位递减计数器CNT即T6, T5, T4, T3, T2, T1, T0。最高位T6是判断超时的关键位。看门狗配置寄存器WWDG_CFR包含7位窗口值W6:0。它用来设定喂狗的“时间窗口”上限。比较器与复位逻辑核心所在图中标注了比较逻辑当 T6:0 W6:0 比较结果 1。同时有一个“写入 WWDG_CR”即喂狗操作的信号。复位逻辑如何触发复位结合图中的逻辑门一个与门 AND一个或门 ORWWDG产生复位信号有两个途径途径一喂狗太早窗口外喂狗当程序执行“写入 WWDG_CR”喂狗时比较器会判断当前计数器的值T6:0是否大于窗口值W6:0。如果T6:0 W6:0即计数器的值还很大处于窗口上限之外比较器输出1。此时与门AND两个输入均为1输出1给或门OR触发复位。途径二喂狗太晚超时图左侧有一条从T6位直接引出连接到或门OR的线。W参看图下方6位递减计数器初始通常设为0x7F即全1T61。当计数器递减到0x3F时T6位从1变成0T5~T0全为1T6会向或门输出一个1触发复位。WWDG工作特性递减计数器 T[6:0] 的值小于 0x40 时产生复位喂狗太晚原理0x40十进制64是二进制的0100 0000最高位 T61。当计数值递减到0x3F二进制0011 1111时T6位由1变成0。T6位一旦变0硬件直接触发复位。递减计数器在窗口 W[6:0] 外被重新装载时产生复位喂狗太早原理呼应图158中的比较器。如果当前计数值T[6:0] W[6:0]此时去喂狗重装载比较器输出1触发复位。这意味着程序跑得太快、或者干扰导致程序乱喂狗都会被抓出来。递减计数器等于 0x40 时可以产生早期唤醒中断EWI原理这是一个“缓冲机制”。当计数器减到0x40时离死机复位只有一步之遥。如果开启了EWI中断单片机可以跳进中断服务函数在这里紧急喂一次狗重装载从而避免复位。这常用于在复位前保存关键数据。定期写入 WWDG_CR 寄存器喂狗以避免复位这是正常操作必须在合法的“刷新窗口”内执行。图159窗口看门狗时序图精讲这张图完美地将上述文字转化成了可视化的时间轴纵轴计数器值从顶部的初始值通常是0x7F开始随着时间横轴向右递减。禁止刷新区W[6:0] 之上斜线处于高位时属于“禁区”。此时如果执行喂狗会立刻触发复位。刷新窗口W[6:0] 到 0x3F 之间斜线穿过 W 值后进入“安全区”。此时喂狗计数器重置回顶部一切正常。喂狗太晚降至 0x3F看图表最下方当计数器触及3Fh时T6位波形图由高变低T6位翻转。复位波形图立刻产生一个脉冲高电平单片机复位。通俗比喻理解跳伞理论如果您觉得寄存器逻辑绕口可以把WWDG想象成跳伞初始值0x7F刚从飞机跳下高度很高。窗口值 W[6:0]安全开伞的最高高度。0x3F 红线安全开伞的最低高度地面。喂狗拉开降落伞。WWDG的逻辑就是如果在最高高度之上就开伞喂狗太早降落伞会被强气流撕碎复位。如果一直不掉高度跌破最低高度喂狗太晚直接摔到地上T6位变0复位。只有在这两个高度之间刷新窗口拉开降落伞才能安全着陆。EWI中断相当于你的高度计在极度接近最低高度时发出的“滴滴”警报提醒你赶紧拉伞。WWDG超时时间1. 超时时间公式TPCLK1APB1总线时钟的周期即 1/FPCLK11/FPCLK1​。4096这是WWDG内部固定的分频值212212。PCLK1进入看门狗后会先固定除以4096然后再进入WDGTB分频器。WDGTB预分频系数下方表格补充了公式即 2WDGTB2WDGTB。WDGTB取值0,1,2,3对应分频系数 1, 2, 4, 8。(T[5:0]1)计数器从初值递减到 0x3F 的节拍数。T[5:0]最大为0x3F即63所以最大计数值是64。一句话总结超时时间 PCLK1时钟周期 × 4096 × 时基分频 × 计数器节拍数。2. 窗口时间公式这里的 T[5:0]通常指的是计数器的初始值即通常配置为0x3F也就是63。W[5:0] 是配置寄存器中设定的窗口值。物理意义这个公式算出来的其实是“从初值递减到窗口值所需的时间”。也就是禁止喂狗的“安全等待期”。注意避坑真正的“允许喂狗的黄金窗口期”是“超时时间减去窗口时间”即从窗口值降到 0x3F 的这段时间。数据验算为什么表格是这些数字我们用下方表格里的PCLK1 36MHz来验证一下36MHz周期 ≈ 27.78ns基础节拍时间 27.78ns×4096≈113.78μs即WDGTB0时的时钟周期。WDGTB 0 (分频1)最小超时值T[5:0]0113.78μs×(01)113.78μs表格为 113μs吻合最大超时值T[5:0]63113.78μs×(631)7281.9μs≈7.28ms表格为 7.28ms吻合WDGTB 3 (分频8)基础节拍变为 113.78μs×8910.24μs113.78μs×8910.24μs最大超时值910.24μs×6458255μs≈58.25msIWDG和WWDG对比IWDG示例Key函数一定要有while;按下按键-模拟停止喂狗#include stm32f10x.h #include Delay.h #include OlED.h #include Key.h int main(void) { //初始化 OLED_Init(); //按键初始化 KeyInit(); OLED_ShowString(1, 1, IWDG TEST); if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) SET) { OLED_ShowString(2, 1, IWDGRST); Delay_ms(500); OLED_ShowString(2, 1, ); Delay_ms(100); RCC_ClearFlag(); } else { OLED_ShowString(3, 1, RST); Delay_ms(500); OLED_ShowString(3, 1, ); Delay_ms(100); } /* IWDG 独立看门狗初始化 * IWDG 时钟来源内部低速 LSI ≈ 40kHz与主频无关故独立 * 溢出时间公式T (4 × 2^prescaler × (reload 1)) / 40kHz * 本配置prescaler 16reload 2499 * T (4 × 16 × 2500) / 40000 4 s /... */ // 1. 写使能IWDG 的 PR/RLR 寄存器受写保护必须先解锁才能修改 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 2. 设置预分频LSI(40kHz) 先固定 4 分频再乘本预分频系数 // 这里选 16即进入计数器的时钟 40kHz / 4 / 16 625Hz IWDG_SetPrescaler(IWDG_Prescaler_16); // 3. 设置重装载值计数器从 reload 递减到 0 即产生复位 // 重装值 2499 → 实际计数 2500 次 // 溢出时间 2500 / 625Hz 4 s见下方说明 IWDG_SetReload(2499); // 4. 喂狗把计数器重新装回 reload 值从头开始倒数 // 必须在 IWDG_Enable() 之前先喂一次保证初始计数值正确 IWDG_ReloadCounter(); // 5. 使能 IWDG启动看门狗 // 一旦使能除复位外无法关闭此后必须周期喂狗否则溢出复位 IWDG_Enable(); while(1) { if (presskey() 0) { //喂狗 IWDG_ReloadCounter(); OLED_ShowString(4, 1, FEED); Delay_ms(200); OLED_ShowString(4, 1, ); Delay_ms(600); } } return 0; }WWDG示例
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进