【STM32】[特殊字符] WWDG(窗口看门狗)学习笔记

发布于:2025-06-28 ⋅ 阅读:(19) ⋅ 点赞:(0)

🧾 STM32 WWDG(窗口看门狗)学习笔记


🔧 一、基本概念

WWDG(Window Watchdog) 是 STM32 内置的一种硬件看门狗定时器,主要用于系统故障检测与自动复位

  • 🧠 工作方式:
    从设定值递减计数器,必须在指定时间窗口内重装(喂狗),否则复位系统。

  • ✅ 目的:
    监控主程序是否卡死、失控或未按时执行关键任务。


🧩 二、关键参数说明

参数 含义 取值范围 备注
Prescaler 预分频器 1, 2, 4, 8 控制计数递减速度,计数时钟 = PCLK1/(4096×Prescaler)
Counter Value 自由递减计数器初始值 64(0x40)~~127(0x7F) 每次喂狗时写入该值
Window Value 喂狗窗口上限 64(0x40)~~127(0x7F) 计数器值必须 ≤ Window 且 ≥ 64 时喂狗
EWI (Early Wakeup Interrupt) 计数器到达 64 触发中断 启用/禁用 可提前执行紧急处理,保存数据等

📐 三、计数时钟计算

计数器递减频率(单位 Hz):

f WWDG = P C L K 1 4096 × Prescaler f_{\text{WWDG}} = \frac{PCLK1}{4096 \times \text{Prescaler}} fWWDG=4096×PrescalerPCLK1

  • 例如:
    PCLK1 = 180 MHz, Prescaler = 8
    则:
    f ≈ 180 , 000 , 000 4096 × 8 = 5493  Hz f \approx \frac{180,000,000}{4096 \times 8} = 5493 \text{ Hz} f4096×8180,000,000=5493 Hz
    每次递减周期约 182 μ s 182 \mu s 182μs

🧮 四、超时时间估算

最大超时时间:

T timeout = ( C o u n t e r − 64 ) × 1 f WWDG T_{\text{timeout}} = (Counter - 64) \times \frac{1}{f_{\text{WWDG}}} Ttimeout=(Counter64)×fWWDG1

  • 例如,Counter = 127,Prescaler = 8,PCLK1 = 180 MHz
  • 递减步数 = 127 - 64 = 63
  • 超时时间 = 63 × 182 μ s ≈ 11.5 m s 63 \times 182 \mu s \approx 11.5 ms 63×182μs11.5ms

⏳ 五、窗口机制说明

  • 只有当计数器值满足:

    64 ≤ Counter ≤ Window 64 \leq \text{Counter} \leq \text{Window} 64CounterWindow

    才允许喂狗。

  • 过早喂狗(Counter > Window)会触发复位。

  • 过晚喂狗(Counter < 64)会触发复位。


🚨 六、Early Wakeup Interrupt(EWI)

  • 计数器递减到 64(0x40)时触发中断。

  • 该中断只会被硬件清除复位后才有效。

  • 提供“最后抢救”机会,可用来:

    • 记录故障信息
    • 保存重要数据(Flash、RAM)
    • 触发报警指示等
  • 注意: EWI 只有在系统未完全死机且中断响应正常时才会触发。


⚠️ 七、常见问题与误区

问题 原因 建议
看门狗一上电就复位 Counter = Window = 64,窗口过窄 设置更大的 Counter 和 Window,扩展喂狗时间窗口
喂狗失败,程序经常复位 喂狗时机不对(早或晚) 使用定时器或任务同步确保喂狗时间精准,避免“早喂”“晚喂”
程序死机未复位 未启用看门狗 确保正确配置并使能看门狗
没有保存数据 程序完全卡死或未启用 EWI 启用 EWI 中断,在中断内保存关键数据
中断不触发 NVIC 未使能,或 EWI 未设置 确保 NVIC 使能 WWDG_IRQn,且打开 EWI 模式

✅ 八、示例配置代码(PCLK1 = 45 MHz 实际示例)

WWDG_HandleTypeDef hwwdg;

void MX_WWDG_Init(void)
{
    hwwdg.Instance = WWDG;
    hwwdg.Init.Prescaler = WWDG_PRESCALER_8;   // 预分频8
    hwwdg.Init.Window = 100;                    // 窗口值100
    hwwdg.Init.Counter = 127;                   // 初始计数127
    hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;      // 使能 EWI 中断
    if (HAL_WWDG_Init(&hwwdg) != HAL_OK)
    {
        Error_Handler();
    }

    // 使能中断优先级及中断
    HAL_NVIC_SetPriority(WWDG_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(WWDG_IRQn);
}

🛠️ 九、中断服务及喂狗示例

void WWDG_IRQHandler(void)
{
    HAL_WWDG_IRQHandler(&hwwdg);
}

void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
{
    // 翻转 GPIO,比如 PE9(LED)
    HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_9);

    // 喂狗,重装计数器,防止复位
    HAL_WWDG_Refresh(hwwdg);
}

🔄 十、主循环示例

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_WWDG_Init();

    while (1)
    {
        // 主循环无需主动喂狗,交给 EWI 中断处理
    }
}

📌 十一、CubeMX 查看 PCLK1 时钟频率

  1. 打开 CubeMX 工程,点击顶部的 Clock Configuration 标签。
  2. 找到 APB1 clock (PCLK1) 数值(单位 MHz),确认实际频率。
  3. 以此频率计算 WWDG 计数时钟,确认超时时间是否合理。

🎯 十二、RTOS 环境下建议

  • 创建专门监控任务,周期检查系统健康。
  • 健康时调用喂狗,异常时停止喂狗以触发复位。
  • 利用 EWI 做故障日志记录。
  • 合理设置 Prescaler、Window、Counter,保证窗口足够宽,避免频繁复位。

⚙️ 十三、计算示例(PCLK1 = 45 MHz)

参数 计算过程 结果
Prescaler 8
计数频率 45,000,000 / (4096 × 8) 1373 Hz
计数周期 1 / 1373 728 μs
递减次数 127 - 64 = 63
最大超时时间 63 × 728 μs 45.86 ms
喂狗安全窗口宽度 (Window - 64) × 728 μs (Window=100) 36 × 728 μs ≈ 26.2 ms

📝 备注

  • Window 值越大,喂狗窗口越宽,越容易稳定
  • Counter 值越大,超时时间越长
  • Prescaler 越大,计数递减越慢,超时时间越长
  • 请务必结合实际时钟频率调整参数!

网站公告

今日签到

点亮在社区的每一天
去签到