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保序。两个一起用,制氧机才能在各种恶劣环境下稳定运行。你想想看,病人吸着氧,机器突然复位——这种事故,咱们做医疗的,一次都不能出。