独立看门狗IWDG原理详解

目录

IWDG

原理介绍

工作原理

IWDG寄存器详解

IWDG关键寄存器

[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库函数

IWDG(独立看门狗)库函数概述

初始化IWDG函数

喂狗(刷新计数器)函数

IWDG溢出时间计算

​编辑

IWDG配置步骤


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表示忙)。

配置步骤

  1. 解锁寄存器

    向KR写入0x5555,允许修改PR和RLR。

  2. 设置预分频值

    写入PR寄存器,例如PR=4(64分频)。

  3. 设置重载值

    写入RLR寄存器,例如RLR=625(超时约1秒)。

  4. 启动看门狗

    向KR写入0xCCCC,IWDG开始计数。

  5. 定期喂狗

    在超时前向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_OKHAL_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配置步骤

相关推荐
_Ningye1 小时前
STM32 — 2.2 新建工程
stm32·单片机·嵌入式硬件
森利威尔电子-2 小时前
森利威尔SL3062替代 LM3485 60V降压恒压芯片
单片机·嵌入式硬件·集成电路·芯片·电源芯片
_Ningye2 小时前
STM32 — 3.1 GPIO输出
stm32·单片机·嵌入式硬件
学嵌入式的小杨同学2 小时前
STM32 进阶封神之路(十九):ADC 深度解析 —— 从模拟信号到数字转换(底层原理 + 寄存器配置)
c++·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
青桔柠薯片3 小时前
51单片机(STC89C52RC)学习总结:从裸机编程到外设驱动
嵌入式硬件·学习·51单片机
weiyvyy3 小时前
从开发视角看硬件接口:接口开发的本质与全景图
驱动开发·单片机·嵌入式硬件·硬件工程
老李的森林3 小时前
杂谈--如何与AI高效率的对话
人工智能·stm32·嵌入式硬件·机械
_Ningye4 小时前
STM32 —2.1 软件安装
stm32
weixin_462901974 小时前
esp32wifi的AP模式
单片机·嵌入式硬件
2501_918126914 小时前
学习所有6502写游戏动画的语句
汇编·嵌入式硬件·学习·程序人生·游戏