目录
[KR(Key Register)](#KR(Key Register))
[PR(Prescaler Register)](#PR(Prescaler Register))
[RLR(Reload Register)](#RLR(Reload Register))
[SR(Status Register)](#SR(Status Register))
IWDG介绍
独立看门狗( Independent Watchdog ,通常缩写为 IWDG )主要作用是主要用于检测外界电磁干扰,或硬件异常导致的程序跑飞问题。
IWDG 本质上是一个 12位的递减计数器 。 当计数器的值从某个初始值开始递减,并一直减到0时,系统会产生一个复位信号(IWDG_RESET)。 CPU 在接收到这个复位信号后,会重新启动系统,以确保系统从可能的错误或死锁状态中恢复。
在计数器的值减到 0 之前,如果程序通过特定的 " 喂狗 " 操作(即重置计数器的值)来刷新计数器,那么就不会产生复位信号,系统将继续正常运行。这种" 喂狗 " 操作通常是由程序在正常运行时定期执行的, 以确保IWDG 不会因计数器超时而产生复位信号。
它使用专用的 低速时钟(LSI) 作为时钟源,即使在主时钟发生故障时, IWDG仍然能够继续运行。IWDG 可以在停止模式和待机模式下工作,确保在这些模式下系统仍然受到保护。
工作原理


IWDG寄存器详解
IWDG的寄存器配置直接影响看门狗的工作模式和行为。
IWDG关键寄存器
KR(Key Register)
- 地址偏移:0x00
- 功能 :写入特定值(0xAAAA、0x5555或0xCCCC)控制IWDG的行为。
- 0xAAAA:重载计数器(喂狗)。
- 0x5555:允许访问PR和RLR寄存器。
- 0xCCCC:启动看门狗(一旦启动无法停止)。
PR(Prescaler Register)
- 地址偏移:0x04
- 功能 :设置预分频系数,决定计数器时钟频率。
- 位域:PR[2:0],支持4/8/16/32/64/128/256分频。
- 公式:计数器时钟 = LSI(40kHz) / 预分频值。
RLR(Reload Register)
- 地址偏移:0x08
- 功能 :设置重载值(12位有效),决定超时时间。
- 公式:超时时间 = (RLR + 1) × (预分频值 / LSI频率)。
SR(Status Register)
- 地址偏移:0x0C
- 功能 :状态标志位。
- PVU:预分频值更新中(1表示忙)。
- RVU:重载值更新中(1表示忙)。
配置步骤
-
解锁寄存器
向KR写入0x5555,允许修改PR和RLR。
-
设置预分频值
写入PR寄存器,例如PR=4(64分频)。
-
设置重载值
写入RLR寄存器,例如RLR=625(超时约1秒)。
-
启动看门狗
向KR写入0xCCCC,IWDG开始计数。
-
定期喂狗
在超时前向KR写入0xAAAA,防止复位。
注意事项
- IWDG一旦启动无法通过软件关闭,只能通过复位或电源周期停止。
- 调试模式下需配置DBGMCU寄存器,避免看门狗触发。
- LSI时钟可能存在偏差,需根据实际校准值调整超时时间。
IWDG库函数
IWDG(独立看门狗)库函数概述
通过库函数配置IWDG,可以设定超时时间并定期"喂狗"以复位计数器。以下为基于STM32标准外设库或HAL库的常用函数及用法。
初始化IWDG函数
c
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
- 参数 :
hiwdg是指向IWDG_HandleTypeDef结构体的指针,包含看门狗的配置信息。 - 返回值 :
HAL_StatusTypeDef枚举值,表示初始化状态(如HAL_OK、HAL_ERROR等)。
IWDG_HandleTypeDef 结构体
cpp
typedef struct {
IWDG_TypeDef *Instance; /* IWDG 寄存器基地址 */
IWDG_InitTypeDef Init; /* IWDG 初始化参数 */
} IWDG_HandleTypeDef;
示例代码
cpp
#include "stm32f4xx_hal.h"
IWDG_HandleTypeDef hiwdg;
void IWDG_Init(void) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
hiwdg.Init.Reload = 0xFFF;
if (HAL_IWDG_Init(&hiwdg) != HAL_OK) {
Error_Handler();
}
}
void main(void) {
HAL_Init();
SystemClock_Config();
IWDG_Init();
while (1) {
HAL_Delay(1000);
HAL_IWDG_Refresh(&hiwdg);
}
}
喂狗(刷新计数器)函数
需在超时前调用喂狗函数,否则系统复位。
c
HAL_IWDG_Refresh(&hiwdg);
看门狗计数器会不断递减,若在计数器归零前未调用
HAL_IWDG_Refresh,系统会被强制复位。刷新操作通过向IWDG_KR寄存器写入0xAAAA(即"喂狗"),将重载值(IWDG_RLR)重新加载到计数器。
示例代码
c
IWDG_HandleTypeDef hiwdg;
void IWDG_Init(void) {
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_256; // 预分频值
hiwdg.Init.Reload = 4095; // 重载值
HAL_IWDG_Init(&hiwdg);
}
int main(void) {
HAL_Init();
IWDG_Init();
while (1) {
HAL_IWDG_Refresh(&hiwdg);
HAL_Delay(500); // 刷新间隔需小于超时时间
}
}
IWDG溢出时间计算
LSI 时钟频率并不精确, RC 频率会在 30kHz 到 60kHz 之间变化 , F1 用 40kHz 进行计算即可。
实际应用中公式中的+1或不+1都无所谓,因为是粗略的

IWDG配置步骤

