前言:曾经刚开始学习单片机的时候,老是会听说一个关于看门狗的概念,猛地一听非常的懵逼,但是随着学习的深入发现这个东西其实就是一个硬件定时器,只不过是功能是为了监测系统运行的稳定性,如果出现系统异常就会触发复位,其作用被人们形象的称之为看门狗。哈哈,不过如此,虽然简单,但还是要介绍一下,仅供大家参考学习。
1,看门狗简介
看门狗是一种硬件定时器,用于监控系统的运行状态。如果系统由于软件错误或硬件故障导致无法正常工作时,看门狗会在设定的时间内未被“喂狗”(即重置定时器)时,自动复位系统,从而恢复系统的正常运行。
STM32G474提供了两种看门狗外设:
-
独立看门狗(IWDG):基于独立的低速内部时钟(LSI),适用于需要高可靠性的场合。
-
窗口看门狗(WWDG):基于APB1总线时钟,适用于需要精确时间窗口监控的场合。
以下详细介绍参考官方提供的参考手册:估计这大家读一篇就会对于这个外设功能有一个详细的了解。
1.1 独立看门狗(IWDG)
特性
-
独立的时钟源:使用LSI(低速内部时钟),频率约为32 kHz,不受主时钟影响。
-
可配置的预分频器:提供多种预分频系数,调整看门狗的计数周期。
-
12位递减计数器:计数范围从0xFFF到0x000,当计数器达到0x000时,系统复位。
-
硬件看门狗:即使系统进入低功耗模式,看门狗仍然有效。
配置步骤
-
使能IWDG:通过设置IWDG_KR寄存器为0xCCCC,启动独立看门狗。
-
配置预分频器:通过设置IWDG_PR寄存器,选择预分频系数。
-
设置重装载值:通过设置IWDG_RLR寄存器,设置计数器的初始值。
-
喂狗:通过向IWDG_KR寄存器写入0xAAAA,重置计数器。
详细介绍
1,这些设备具有嵌入式看门狗外围设备(IWDG),它提供了高安全性、时间准确性和使用灵活性的组合。该外围设备检测并解决由于软件故障而引起的故障,并在计数器达到给定超时值时触发系统复位。
2,该独立监控器由自己的专用低速时钟(LSI)计时,即使主时钟失效也能保持活动状态。
3,IWDG最适用于需要在主应用程序之外作为一个完全独立的进程运行,但具有较低时间准确性限制的应用程序。
IWDG 主要功能
1,自由运行计数器:由独立的RC振荡器定时(可在待机模式和停止模式下运行)
2,条件重置:当下计数器值低于0x000时重置(如果看门狗被激活),如果下计数器在窗口外重新加载,则重置(如果看门狗被激活)
1.2 窗口看门狗(WWDG)
特性
-
基于APB1时钟:时钟频率较高,适用于需要精确时间窗口监控的场合。
-
可配置的窗口值:设置一个时间窗口,只有在窗口内喂狗才有效,否则系统复位。
-
6位递减计数器:计数范围从0x3F到0x40,当计数器达到0x3F时,系统复位。
-
早期唤醒中断:可以在计数器达到0x40时产生中断,提前处理异常。
配置步骤
-
使能WWDG:通过设置WWDG_CR寄存器的WDGA位,启动窗口看门狗。
-
配置窗口值:通过设置WWDG_CFR寄存器的W位,设置窗口的上限值。
-
设置计数器初始值:通过设置WWDG_CR寄存器的T位,设置计数器的初始值。
-
喂狗:通过向WWDG_CR寄存器写入0x7F,重置计数器。
详细介绍:
1,系统窗口监视器(WWDG)用于检测软件故障的发生,通常由外部干扰或未预见的逻辑条件引起,导致应用程序放弃其正常序列。
2,监控电路会在预定时间到期时生成MCU复位,除非程序在T6位被清除之前刷新下计数器的值。
3,如果在下计数器达到窗口寄存器值之前刷新了7位下计数器值(在控制寄存器中),也会生成MCU复位。这意味着计数器必须在有限的时间窗口内刷新。
4,WWDG时钟是从APB时钟预分频的,并且具有可配置的时间窗口,可以编程以检测异常迟到的或提前的应用程序行为。
5,WWDG最适合需要监控器在精确的时间窗口内做出反应的应用。,
WWDG 主要功能:
1,可编程自由运行减计数器,
2,条件重置
- 复位(如果看门狗激活)当下计数器值低于0x40时
- 复位(如果看门狗激活)如果下计数器在窗口外重新加载
3,早期唤醒中断(EWI):当下计数器等于0x40时触发(如果已启用且看门狗激活)。
2,cubemx看门狗配置
这个配置方法我在前面的文章有过介绍,大家直接查看即可,我当时配置的是IWDG,不过两种配置方法大同小异。
3,看门狗demo代码
虽然简单,还是拿出来供大家参考一下,这个基本上没有太多的比较难理解的东西,上面的这个概念理解了之后配置就是很简单的事情了。
3.1 独立看门狗(IWDG)配置示例
#include "stm32g4xx_hal.h"
IWDG_HandleTypeDef hiwdg;
void SystemClock_Config(void);
static void MX_IWDG_Init(void);
int main(void) {
// 初始化HAL库
HAL_Init();
// 配置系统时钟
SystemClock_Config();
// 初始化IWDG
MX_IWDG_Init();
while (1)
{
// 主循环中定期喂狗
HAL_IWDG_Refresh(&hiwdg);
// 模拟任务运行
HAL_Delay(500); // 每500ms喂一次狗
}
}
// IWDG初始化函数
static void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_32; // 预分频器为32
hiwdg.Init.Reload = 1000; // 重装载值为1000
if (HAL_IWDG_Init(&hiwdg) != HAL_OK) {
// 初始化错误处理
Error_Handler();
}
}
3.2 窗口看门狗(WWDG)配置示例
#include "stm32g4xx_hal.h"
WWDG_HandleTypeDef hwwdg;
void SystemClock_Config(void);
static void MX_WWDG_Init(void);
int main(void)
{
// 初始化HAL库
HAL_Init();
// 配置系统时钟
SystemClock_Config();
// 初始化WWDG
MX_WWDG_Init();
while (1) {
// 主循环中定期喂狗
HAL_WWDG_Refresh(&hwwdg);
// 模拟任务运行
HAL_Delay(50); // 每50ms喂一次狗
}
}
// WWDG初始化函数
static void MX_WWDG_Init(void)
{
hwwdg.Instance = WWDG;
hwwdg.Init.Prescaler = WWDG_PRESCALER_8; // 预分频器为8
hwwdg.Init.Window = 0x50; // 窗口值为0x50
hwwdg.Init.Counter = 0x7F; // 计数器初始值为0x7F
hwwdg.Init.EWIMode = WWDG_EWI_DISABLE; // 禁用早期唤醒中断
if (HAL_WWDG_Init(&hwwdg) != HAL_OK) {
// 初始化错误处理
Error_Handler();
}
}
// 错误处理函数
void Error_Handler(void) {
while (1) {
// 错误处理逻辑
}
}
完结。。。