独立看门狗(IWDG)
1. IWDG 简介
-
定义:独立看门狗(Independent Watchdog, IWDG)是一种硬件定时器,主要用来防止系统进入死循环、跑飞等异常状态。
-
时钟源:内部低速时钟 LSI(典型值 40kHz),不依赖系统主时钟 (HSE/HSE),即使主时钟故障也能工作。
-
作用:
-
MCU 运行过程中必须定期喂狗(刷新计数器),否则计数器溢出将自动复位 MCU。
-
保证系统在异常时自动恢复运行,提高可靠性。
-
-
特点:
-
独立于 CPU,不能被软件停止,一旦开启只能通过复位关闭。
-
适合工业控制、无人值守设备。
-
2. IWDG 工作原理及框图
工作原理:
-
IWDG 从 LSI 时钟 (40kHz) 获取时钟输入。
-
通过 预分频器 (Prescaler) 进行分频,得到计数时钟。
-
计数器 递减计数,当减到 0 → 触发系统复位。
-
软件需定期写入 刷新寄存器 (IWDG_KR = 0xAAAA),重新装载计数器,避免复位。
框图(简化版):
LSI (40kHz)
│
[预分频器]
│
[12位递减计数器]
│
计数到0 → 触发复位
3. IWDG 寄存器及函数介绍
关键寄存器
-
KR (Key Register, 0x00)
-
写入
0xCCCC→ 启动 IWDG -
写入
0xAAAA→ 喂狗(刷新计数器) -
写入
0x5555→ 允许修改预分频器和重装载寄存器
-
-
PR (Prescaler Register, 0x04)
-
设置预分频系数,取值范围:
4, 8, 16, 32, 64, 128, 256
-
-
RLR (Reload Register, 0x08)
-
设置重载值 (0 ~ 0xFFF)
-
计数器每次刷新后从 RLR 装载,向下递减
-
-
SR (Status Register, 0x0C)
-
标志位:PR/RLR 是否正在更新,防止写入冲突
-
HAL 库函数
-
HAL_IWDG_Init():初始化并启动 IWDG -
HAL_IWDG_Refresh():喂狗,刷新计数器 -
__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST):判断是否 IWDG 复位 -
__HAL_RCC_CLEAR_RESET_FLAGS():清除复位标志
4. IWDG 溢出时间计算
公式:

-
RLR:重载值 (0 ~ 4095) -
Prescaler:分频系数 (4,8,16,32,64,128,256) -
LSI_Freq:LSI 时钟频率 (典型值 40kHz)
例子(你代码里的参数):
-
psc = 32,RLR = 1250

这意味着:如果 1s 内没有喂狗 → MCU 会复位。
5. IWDG 配置步骤
-
开启 LSI 时钟(CubeMX 自动配置,手动时需打开)
-
解锁 PR/RLR:写
0x5555到 KR -
设置预分频器 PR、重载值 RLR
-
启动 IWDG:写
0xCCCC到 KR -
周期性喂狗:写
0xAAAA到 KR
补充知识点
-
复位标志判断:通过
RCC_FLAG_IWDGRST区分是否由 IWDG 复位。 -
与窗口看门狗 (WWDG) 区别:
-
IWDG 独立时钟,无法停止;WWDG 用主时钟,复位前可产生中断。
-
-
典型应用:无人值守设备(采集器、传感器节点、逆变器控制器、工业控制器)。
总结一句话:
独立看门狗 (IWDG) = “硬件定时器 + 强制复位”,定期喂狗保证程序正常运行,否则 MCU 自动复位。
STM32F103 独立看门狗 (IWDG) 实验
main.c
#include "sys.h" // 系统时钟初始化相关函数
#include "delay.h" // 延时函数(ms、us)
#include "led.h" // LED 控制函数
#include "uart1.h" // 串口1初始化与收发
#include "iwdg.h" // 独立看门狗 IWDG 驱动
int main(void)
{
HAL_Init(); /* 初始化 HAL 库:包括 NVIC 分组、SysTick 配置等 */
stm32_clock_init(RCC_PLL_MUL9); /* 系统时钟设置为 72MHz (HSE=8MHz, PLL*9) */
led_init(); /* 初始化板载 LED */
uart1_init(115200); /* 初始化串口1,波特率 115200 */
/* 初始化独立看门狗 IWDG
* 参数1 Prescaler:预分频器,取值 IWDG_PRESCALER_x
* 参数2 Reload:重载值,计数到0则触发复位
* 本例:psc=32,rlr=1250
* 时钟源固定为 LSI = 40kHz (典型值)
* IWDG 超时时间 = (Reload+1) * Prescaler / 40kHz
* = (1250+1) * 32 / 40000 ≈ 1.0 s
*/
iwdg_init(IWDG_PRESCALER_32, 1250);
printf("hello world!\r\n");
printf("狗儿肚子饿了,再不喂它的话就咬人了!\r\n");
/* 判断复位原因:是否由独立看门狗触发 */
if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET) // 读取 RCC 寄存器复位标志
{
printf("独立看门狗复位!\r\n");
__HAL_RCC_CLEAR_RESET_FLAGS(); // 清除复位标志,防止下次开机误判
}
else
printf("外部复位!\r\n"); // 若不是IWDG复位,则说明是上电/手动复位
while(1)
{
delay_ms(1500); // 延时 1500ms (> 1s 看门狗溢出时间)
iwdg_feed(); // 喂狗(刷新计数器,防止复位)
printf("狗儿已经喂饱了,不会咬人了!\r\n");
}
}
iwdg.c
#include "iwdg.h"
IWDG_HandleTypeDef iwdg_handle = {0}; // 定义 IWDG 句柄,全局变量
/* 独立看门狗初始化
* 参数 psc:预分频器 (IWDG_PRESCALER_x)
* 参数 rlr:重载值 (0~0xFFF)
*/
void iwdg_init(uint8_t psc, uint16_t rlr)
{
iwdg_handle.Instance = IWDG; // 指定硬件实例为 IWDG 外设
iwdg_handle.Init.Prescaler = psc; // 设置预分频器 (2,4,8,16,32,64,128,256)
iwdg_handle.Init.Reload = rlr; // 设置重载值 (0~4095)
HAL_IWDG_Init(&iwdg_handle); // 调用 HAL 库函数,写入寄存器并启动看门狗
}
/* 喂狗函数
* 功能:刷新计数器,防止看门狗复位
* 本质:往 IWDG_KR 寄存器写入 0xAAAA
*/
void iwdg_feed(void)
{
HAL_IWDG_Refresh(&iwdg_handle);
}
实验现象
-
程序启动时
-
串口打印:
-
hello world!
狗儿肚子饿了,再不喂它的话就咬人了!
外部复位!
LED 初始化完成(如点亮/熄灭,看 led_init() 定义)。
-
进入 while(1) 循环
-
延时 1500 ms,超过 IWDG 超时时间 (~1s)。
-
但在延时结束后才喂狗。
-
-
结果
-
在大多数情况下,看门狗会在 1s 左右复位 MCU,根本来不及执行
iwdg_feed()。 -
复位后再次启动,程序会检测到
RCC_FLAG_IWDGRST,于是串口打印:
-
独立看门狗复位!
如果把 delay_ms(1500) 改小于 1000ms(比如 500ms),则能正常喂狗,程序不会复位,每 1.5s 打印:
狗儿已经喂饱了,不会咬人了!
所以现象分两种:
-
延时 < 超时时间 → 程序一直运行,循环打印“狗儿已经喂饱了”。
-
延时 > 超时时间 → 程序不断复位,循环打印“独立看门狗复位”。
参数的可选项
A. iwdg_handle.Init.Prescaler
HAL 库定义的宏:
-
IWDG_PRESCALER_4 -
IWDG_PRESCALER_8 -
IWDG_PRESCALER_16 -
IWDG_PRESCALER_32 -
IWDG_PRESCALER_64 -
IWDG_PRESCALER_128 -
IWDG_PRESCALER_256
作用:决定 IWDG 时钟分频系数(基于 LSI ~40kHz)。
B. iwdg_handle.Init.Reload
-
取值范围:
0x000 ~ 0xFFF(即 0 ~ 4095)。 -
重载寄存器值,计数到 0 时触发复位。
超时时间公式:

例:
-
psc = 32, rlr = 1250 → 超时时间 ≈ 1.0 s
-
psc = 64, rlr = 4000 → 超时时间 ≈ 6.4 s
C. __HAL_RCC_GET_FLAG() 可选标志(对应STM32中文参考手册V10)
-
RCC_FLAG_IWDGRST→ 独立看门狗复位 -
RCC_FLAG_WWDGRST→ 窗口看门狗复位 -
RCC_FLAG_PINRST→ 外部复位 (NRST 引脚) -
RCC_FLAG_PORRST→ 上电复位 -
RCC_FLAG_SFTRST→ 软件复位(写 AIRCR 寄存器触发)
用于判断 MCU 上一次复位的原因。
总结
-
代码注释:逐行解释了看门狗初始化、喂狗流程。
-
实验现象:
-
delay_ms < 超时时间→ 程序正常运行。 -
delay_ms > 超时时间→ MCU 会反复复位,并打印“独立看门狗复位”。
-
-
参数说明:
-
预分频器:
IWDG_PRESCALER_4 ~ 256。 -
重载值:
0 ~ 4095,决定溢出时间。 -
复位标志:可区分 IWDG、WWDG、外部复位、上电复位、软件复位。
-
更多推荐


所有评论(0)