阿杰 👍
你问的是 STM32 的看门狗 (Watchdog, WDG),我帮你系统整理一下:
🐶 STM32 看门狗 (Watchdog)
在 STM32 中常见两种看门狗:
- 独立看门狗(IWDG,Independent Watchdog)
- 时钟源:低速内部时钟 LSI (32 kHz 左右)
- 完全独立于主系统时钟,掉电复位/系统死机也能复位
- 常用于系统挂死时自动复位
- 一旦开启,只能通过复位 MCU 才能关闭
- 窗口看门狗(WWDG,Window Watchdog)
- 时钟源:PCLK1 (APB1 时钟)
- 在一个“时间窗口”内刷新,如果太早或太晚都会复位
- 可检测程序运行是否过快/过慢(适合实时性要求更严格的系统)
🟢 独立看门狗 IWDG 使用流程
- 开启 LSI 时钟
- 配置预分频器、重装载寄存器(决定超时时间)
- 启动 IWDG
- 在主循环或定时任务中定期 喂狗(刷新计数器)
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 使用流程
- 配置 WWDG 时钟分频和窗口值
- 启动 WWDG
- 在合适时间窗口内刷新计数器(早了/晚了都会复位)
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
特性 | IWDG | WWDG |
---|---|---|
时钟源 | LSI 独立时钟 | PCLK1 (APB1 总线时钟) |
独立性 | 与主系统无关,掉电也运行 | 依赖系统时钟 |
配置灵活性 | 一旦开启不能关闭 | 可以关闭或重新配置 |
用途 | 防止系统死机,最终兜底 | 检测代码执行是否及时、合理 |
📌 实际应用建议
- 普通容错:IWDG(最常用,保证设备不会死机)
- 实时性要求高:WWDG(检测卡死/跑飞/跑太快)
- 两者结合:WWDG 检测运行异常,IWDG 作为最后保障
发表回复