2. 硬件看门狗选型:STM32独立看门狗(IWDG) vs 窗口看门狗(WWDG)对比
做医疗制氧机,选看门狗是个绕不开的坎。我见过不少同行,随便选个IWDG就往上怼,结果产品在强电磁干扰下频繁复位,病人吸着氧突然机器重启——这可不是闹着玩的。
今天咱们就把STM32的两种看门狗掰开揉碎讲清楚。你想想看,一个负责「死透了就拉起来」,一个负责「别跑偏了赶紧纠正」,用法完全不同。
2.1 独立看门狗(IWDG) —— 最后的保命符
IWDG说白了就是一个独立于主系统的定时器。它有自己的时钟源(LSI,大概40kHz),就算主时钟挂了,它照样能跑。我习惯把它叫做「终极保险丝」。
核心特点:
- 使用独立的RC振荡器(LSI),与主时钟无关
- 只有「递减计数」模式,到0就复位
- 喂狗窗口:从启动到计数器归零之前都可以喂
- 超时范围:约0.1ms到26.3秒(取决于预分频和重装载值)
我在一个制氧机项目中遇到过这种情况:电机驱动产生强干扰,把主晶振都打偏了。系统时钟乱跳,但IWDG依然稳稳地走着。嗯,这就是它存在的意义——主系统再乱,它也不乱。
2.2 窗口看门狗(WWDG) —— 精准的时间警察
WWDG就不一样了。它用的是系统时钟(APB1),精度高,但依赖主时钟。它的特殊之处在于——喂狗不能太早,也不能太晚。
核心特点:
- 使用APB1时钟(通常几十MHz),精度高
- 有「上窗口」和「下窗口」限制
- 必须在窗口期内喂狗,否则复位
- 超时范围:约0.1ms到几百ms(取决于分频和窗口值)
为什么会设计这种「窗口」机制?我举个例子你就明白了。假设你的程序跑飞了,但碰巧在某个循环里不断喂IWDG,那IWDG永远发现不了问题。但WWDG不一样——如果你喂得太快(说明程序可能卡死在某个快速循环里),它照样复位你。
2.3 关键参数对比表
| 对比项 | IWDG | WWDG |
|---|---|---|
| 时钟源 | LSI(约40kHz,独立) | APB1(依赖主时钟) |
| 时钟精度 | 低(±10%~20%) | 高(与晶振精度一致) |
| 喂狗方式 | 任意时刻喂 | 必须在窗口内喂 |
| 超时精度 | 粗放 | 精细 |
| 抗时钟失效 | 强(独立运行) | 弱(时钟挂了它也挂) |
| 典型应用 | 系统级死锁保护 | 任务时序监控 |
2.4 实战选型建议
在医疗制氧机里,我的做法是——两个都用。但分工不同:
我的推荐方案:
- IWDG:作为系统级保护,超时设为5~10秒。专门对付「主时钟挂了」「CPU彻底死机」这种极端情况。
- WWDG:作为任务级监控,超时设为50~200ms。监控RTOS的任务调度是否正常,每个关键任务是否按时执行。
我曾经在一个制氧机项目中,只用了IWDG。结果发现,当某个中断服务函数卡死时,IWDG根本检测不到——因为中断里还在喂狗!后来加上WWDG,把喂狗点放在任务级的固定位置,问题才解决。
2.5 代码示例:IWDG初始化
// IWDG初始化,超时约4秒(LSI=40kHz,预分频64,重装载2500)
void IWDG_Init(void)
{
// 使能写访问
IWDG->KR = 0x5555;
// 设置预分频为64
IWDG->PR = IWDG_Prescaler_64;
// 设置重装载值
IWDG->RLR = 2500;
// 等待寄存器更新
while(IWDG->SR != 0);
// 启动看门狗
IWDG->KR = 0xCCCC;
// 首次喂狗
IWDG->KR = 0xAAAA;
}
2.6 代码示例:WWDG初始化
// WWDG初始化,窗口上限0x7F,下限0x40,超时约50ms(APB1=72MHz)
void WWDG_Init(void)
{
// 使能WWDG时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
// 设置窗口值:必须在计数器降到0x40之前喂狗
WWDG->CFR = (7 << 7) | 0x40; // 分频系数=8,窗口下限=0x40
// 设置计数器初始值
WWDG->CR = 0x7F; // 从0x7F开始递减
// 使能WWDG
WWDG->CR |= (1 << 7);
}
重要提醒:
- IWDG一旦启动,除了复位无法停止。调试时记得在仿真器里禁用,否则断点一停就复位。
- WWDG的窗口值计算要留余量。我习惯把窗口设得比任务最坏执行时间宽30%,避免误复位。
- 医疗设备中,两个看门狗都要有独立的喂狗任务,且喂狗任务优先级要低于被监控的任务。
2.7 避坑指南
我曾经踩过一个坑:在制氧机的压力控制任务里,用DMA传输数据。DMA传输期间CPU可以干别的,但喂狗任务不知道DMA什么时候结束。结果WWDG频繁复位——因为喂狗时机不对。
后来怎么解决的?我把喂狗点放在DMA传输完成中断里,确保每次数据传输完成后才喂狗。这样既保证了时序正确,又不会误复位。
另一个坑是IWDG的时钟精度。LSI在不同温度下频率会漂移,常温下40kHz,到了-20℃可能只有32kHz。所以计算超时时间时,我建议按最差情况算——留出50%的余量。
嗯,选型这事儿,说白了就是权衡。IWDG保底,WWDG保序。两个一起用,制氧机才能在各种恶劣环境下稳定运行。你想想看,病人吸着氧,机器突然复位——这种事故,咱们做医疗的,一次都不能出。