阿杰 👍
你问的是 STM32 的看门狗 (Watchdog, WDG),我帮你系统整理一下:


🐶 STM32 看门狗 (Watchdog)

在 STM32 中常见两种看门狗:

  1. 独立看门狗(IWDG,Independent Watchdog)
    • 时钟源:低速内部时钟 LSI (32 kHz 左右)
    • 完全独立于主系统时钟,掉电复位/系统死机也能复位
    • 常用于系统挂死时自动复位
    • 一旦开启,只能通过复位 MCU 才能关闭
  2. 窗口看门狗(WWDG,Window Watchdog)
    • 时钟源:PCLK1 (APB1 时钟)
    • 在一个“时间窗口”内刷新,如果太早或太晚都会复位
    • 可检测程序运行是否过快/过慢(适合实时性要求更严格的系统)

🟢 独立看门狗 IWDG 使用流程

  1. 开启 LSI 时钟
  2. 配置预分频器、重装载寄存器(决定超时时间)
  3. 启动 IWDG
  4. 在主循环或定时任务中定期 喂狗(刷新计数器)

HAL 库示例

#include "stm32f1xx_hal.h"

IWDG_HandleTypeDef hiwdg;

void MX_IWDG_Init(void)
{
    hiwdg.Instance = IWDG;
    hiwdg.Init.Prescaler = IWDG_PRESCALER_64;   // 分频因子
    hiwdg.Init.Reload    = 1000;                // 重装值(越大超时时间越长)
    HAL_IWDG_Init(&hiwdg);
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_IWDG_Init();   // 初始化看门狗

    while (1)
    {
        HAL_Delay(100);   // 模拟任务
        HAL_IWDG_Refresh(&hiwdg);  // 喂狗,避免复位
    }
}

计算超时时间公式:

Tout = (预分频值 * 重装载值) / LSI频率

例:Prescaler=64, Reload=1000, LSI=32kHz
Tout ≈ (64 * 1000) / 32000 = 2 秒


🔵 窗口看门狗 WWDG 使用流程

  1. 配置 WWDG 时钟分频和窗口值
  2. 启动 WWDG
  3. 在合适时间窗口内刷新计数器(早了/晚了都会复位)

HAL 库示例

#include "stm32f1xx_hal.h"

WWDG_HandleTypeDef hwwdg;

void MX_WWDG_Init(void)
{
    hwwdg.Instance       = WWDG;
    hwwdg.Init.Prescaler = WWDG_PRESCALER_8;    // 时钟分频
    hwwdg.Init.Window    = 80;                  // 窗口值
    hwwdg.Init.Counter   = 127;                 // 起始计数
    HAL_WWDG_Init(&hwwdg);
}

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

    while (1)
    {
        HAL_Delay(20);  
        HAL_WWDG_Refresh(&hwwdg);  // 必须在合适时间喂狗
    }
}


⚖️ 对比 IWDG vs WWDG

特性IWDGWWDG
时钟源LSI 独立时钟PCLK1 (APB1 总线时钟)
独立性与主系统无关,掉电也运行依赖系统时钟
配置灵活性一旦开启不能关闭可以关闭或重新配置
用途防止系统死机,最终兜底检测代码执行是否及时、合理

📌 实际应用建议

  • 普通容错:IWDG(最常用,保证设备不会死机)
  • 实时性要求高:WWDG(检测卡死/跑飞/跑太快)
  • 两者结合:WWDG 检测运行异常,IWDG 作为最后保障