3. 看门狗类型:独立看门狗(IWDG)与窗口看门狗(WWDG)的区别

在嵌入式系统中,看门狗定时器是保障系统可靠运行的最后一道防线。根据应用场景与触发机制的不同,主流MCU通常提供两种类型的看门狗:独立看门狗(IWDG)与窗口看门狗(WWDG)。理解二者的本质区别,是设计高可靠性硬件电路的基础。

独立看门狗 (IWDG) 窗口看门狗 (WWDG) 独立时钟源 (LSI ~32kHz) 不受系统时钟影响 12位递减计数器 从0xFFF递减至0x000 复位触发 计数器归零 → 系统复位 喂狗:任意时刻写入重装载值 系统时钟分频 (PCLK) 依赖APB总线时钟 7位递减计数器 (T[6:0]) 从0x7F递减至0x40 窗口机制 必须在“窗口区间”内喂狗 喂狗:必须在窗口内写入 ← 时钟独立性对比 →

▲ 图3-1 IWDG与WWDG内部架构对比示意图

3.1 核心区别总览

对比维度 独立看门狗 (IWDG) 窗口看门狗 (WWDG)
时钟源 独立内部RC振荡器(LSI,约32kHz),与系统主时钟无关 系统时钟(APB1时钟)分频得到,依赖主时钟运行
计数器位数 12位递减计数器(最大计数值4095) 7位递减计数器(最大计数值127)
超时范围 较宽(典型值125μs ~ 32.7s,取决于预分频器) 较窄(典型值约0.1ms ~ 若干ms,取决于时钟与分频)
喂狗机制 任意时刻写入重装载值(只要计数器未到0) 必须在“窗口区间”内喂狗(计数器值在W[6:0]~0x40之间)
复位条件 计数器递减至0x000时产生系统复位 ①计数器递减至0x3F(即T6位清零)
②在窗口上限之外喂狗(过早喂狗)
中断支持 通常无提前中断(部分MCU有早期唤醒中断EWI) 计数器达到0x40时可触发提前中断(EWI),用于执行清理操作
典型应用 系统死机保护、低功耗模式下的监控、对时间精度要求不高的场景 需要精确时序控制、检测程序跑飞或时序异常、安全关键系统

3.2 窗口看门狗的“窗口”机制详解

窗口看门狗最显著的特征是引入了“喂狗窗口”的概念。与独立看门狗“只要在计数器归零前喂狗即可”不同,WWDG要求喂狗操作必须发生在计数器值落入一个特定的数值区间内——既不能太早,也不能太晚。

计数器值 0x7F (127) 0x40 (64) 0x3F (63) 时间 → 允许喂狗窗口 窗口下限 (W[6:0]) 窗口上限 (0x40) 过早喂狗 → 复位 过晚喂狗 → 复位 WWDG 喂狗窗口时序示意图

▲ 图3-2 WWDG喂狗窗口:过早或过晚喂狗均会导致系统复位

3.3 关键设计差异详解

  1. 时钟可靠性:IWDG使用独立的LSI振荡器,即使主时钟因故障停振,IWDG依然能正常工作,这是其最大的可靠性优势。WWDG依赖系统时钟,若主时钟失效,WWDG也将失效。
  2. 时序精度:WWDG基于精确的系统时钟分频,超时时间可控且精度高,适合对时间窗口有严格要求的应用。IWDG的LSI频率受温度、电压影响较大(典型精度±10%~±20%),不适合精确计时。
  3. 故障检测能力:WWDG不仅能检测“程序死机”(计数器归零),还能检测“程序跑飞导致过早喂狗”的异常情况,提供更全面的保护。
  4. 功耗考虑:IWDG在低功耗模式下(如停机、待机)仍可运行,适合电池供电设备。WWDG在MCU进入低功耗模式后通常停止计数。

3.4 典型应用场景对比

✅ 适合使用 IWDG 的场景

  • 系统死机后需要绝对可靠的复位
  • 低功耗待机/停机模式下的监控
  • 主时钟可能失效的恶劣环境
  • 对超时时间精度要求不高的应用
  • 简单的“心跳”式喂狗逻辑

✅ 适合使用 WWDG 的场景

  • 需要精确时序控制的安全系统
  • 检测程序执行流程是否异常(过早/过晚)
  • 工业控制、汽车电子等安全关键领域
  • 需要在复位前执行数据保存/清理操作
  • 多任务系统中检测任务调度是否正常

3.5 代码示例:IWDG 与 WWDG 初始化对比

以下代码展示了在STM32平台上两种看门狗的典型初始化配置,注意时钟源、计数器配置和喂狗方式的差异:

/* ========== 独立看门狗 (IWDG) 初始化 ========== */
void IWDG_Init(void)
{
    // 1. 使能写访问
    IWDG->KR = 0x5555;   // 解锁寄存器
    
    // 2. 设置预分频器:4分频 → 计数频率 = 32kHz / 4 = 8kHz
    IWDG->PR = 0x01;     // PR[2:0] = 001
    
    // 3. 设置重装载值:1000 → 超时时间 ≈ 1000 / 8000 = 125ms
    IWDG->RLR = 1000;
    
    // 4. 等待同步
    while (IWDG->SR & 0x01);
    
    // 5. 启动看门狗(写入0xCCCC)
    IWDG->KR = 0xCCCC;
}

/* 喂狗:任意时刻调用 */
void IWDG_Feed(void)
{
    IWDG->KR = 0xAAAA;   // 重装载计数器
}


/* ========== 窗口看门狗 (WWDG) 初始化 ========== */
void WWDG_Init(void)
{
    // 1. 使能WWDG时钟(APB1)
    RCC->APB1ENR |= RCC_APB1ENR_WWDGEN;
    
    // 2. 配置:计数器初始值=0x7F,窗口值=0x50
    //    分频系数=8 → 计数时钟 = PCLK1 / 4096 / 8
    WWDG->CFR = (0x50 << 7) | (0x03 << 5);  // W[6:0]=0x50, WDGTB[1:0]=11(8分频)
    
    // 3. 使能提前唤醒中断(可选)
    WWDG->CFR |= WWDG_CFR_EWI;
    NVIC_EnableIRQ(WWDG_IRQn);
    
    // 4. 设置计数器初始值并启动
    WWDG->CR = 0x7F | WWDG_CR_WDGA;  // T[6:0]=0x7F, 启动WDGA
}

/* 喂狗:必须在窗口内调用(计数器值在0x50~0x40之间) */
void WWDG_Feed(void)
{
    // 注意:必须在主循环中判断计数器当前值是否在窗口内
    // 此处仅做重装载操作
    WWDG->CR = 0x7F;   // 重装载计数器为0x7F
}

/* WWDG提前唤醒中断服务函数 */
void WWDG_IRQHandler(void)
{
    if (WWDG->SR & WWDG_SR_EWIF) {
        // 执行紧急数据保存等操作
        SaveCriticalData();
        WWDG->SR = 0x00;   // 清除中断标志
    }
}

3.6 选型建议

📌 硬件设计选型决策树

  • 如果系统对时钟故障零容忍 → 必须使用 IWDG(独立时钟源)
  • 如果需要检测程序执行时序异常 → 必须使用 WWDG(窗口机制)
  • 如果两者都需要 → 同时启用 IWDG + WWDG,实现双重保护(IWDG负责死机复位,WWDG负责时序监控)
  • 如果MCU资源有限 → 优先选择 IWDG,配置简单且可靠性高

专注课程资料整理