WWDG(窗口看门狗)
本质:能产生系统复位信号和提前唤醒中断的计数器,再窗口期内重载计数器的值,防止复位
作用:检测窗口异常,程序运行时效是否精确,由系统时钟源提供时钟信号
喂狗需在窗口期,其他时间喂狗都会产生复位
各时期时间计算公式:
配置步骤
1.初始化 HAL_WWDG_Init(&g_wwdg_handle) 设置分频系数和窗口值
2.MSP初始化 HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) 使能和设置优先级
3.编写中断服务函数 WWDG_IRQHandler(void) 调用公共处理函数
4.重新定义提前唤醒回调函数
HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
5.在窗口期喂狗 HAL_WWDG_Refresh(&g_wwdg_handle) 喂狗重装载计数器
其中第一步需要配置两个结构体,一个是WWDG_HandleTypeDef句柄结构体 如下
typedef struct
{
WWDG_TypeDef
*
Instance
;
/* WWDG
寄存器基地址
*/
WWDG_InitTypeDef Init
;
/* WWDG
初始化参数
*/
}
WWDG_HandleTypeDef
;
第二个是
WWDG 初始化结构体WWDG_InitTypeDef ,用于配置计数器的相关参数 如下
typedef struct
{
uint32_t
Prescaler
;
/*
预分频系数1,2,4,8
*/
uint32_t
Window
;
/*
窗口值
*/
uint32_t
Counter
;
/*
计数器值
*/
uint32_t
EWIMode
;
/*
提前唤醒中断使能
*/
}
WWDG_InitTypeDef
;
设置一个计数器值0x7f,窗口值0x5f,预分频8的看门狗
wwdg程序
//wwdg.c
#include "./BSP/WDG/wdg.h"
#include "./BSP/LED/led.h"
WWDG_HandleTypeDef g_wwdg_handle; //定义结构体
//窗口看门狗初始化函数
void wwdg_init(uint8_t tr,uint8_t wr,uint32_t fprer)
{
g_wwdg_handle.Instance = WWDG; //寄存器基地址选择WWDG
g_wwdg_handle.Init.Counter = tr; //计数器初始值
g_wwdg_handle.Init.Window = wr; //窗口值
g_wwdg_handle.Init.Prescaler = fprer; //预分频系数
g_wwdg_handle.Init.EWIMode = WWDG_EWI_ENABLE; //使能中断,会产生中断
HAL_WWDG_Init(&g_wwdg_handle); //初始化结构体 第一步
}
//WWDG.MSP回调函数
void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) //第二步
{
__HAL_RCC_WWDG_CLK_ENABLE(); //使能时钟
HAL_NVIC_SetPriority(WWDG_IRQn, 2, 3);//(中断号,抢占优先级,响应优先级)
HAL_NVIC_EnableIRQ(WWDG_IRQn); //使能中断
}
//WWDG中断服务函数
void WWDG_IRQHandler(void) //第三步
{
HAL_WWDG_IRQHandler(&g_wwdg_handle); //使用公共处理函数
}
//WWDG提前唤醒回调函数
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) //第四步
{
LED1_TOGGLE(); //翻转LED1
}
//wwdg.h
#ifndef __WDG_H
#define __WDG_H
#include "./SYSTEM/sys/sys.h"
extern WWDG_HandleTypeDef g_wwdg_handle;
void wwdg_init(uint8_t tr,uint8_t wr,uint32_t fprer);
#endif
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/WDG/wdg.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
led_init(); /* 初始化LED */
usart_init(115200); //初始化串口
if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != 0) //判断窗口看门狗是否产生复位
{
printf("窗口看门狗复位!!!\r\n");
__HAL_RCC_CLEAR_RESET_FLAGS(); //窗口看门狗清零
}else
{
printf("外部复位!\r\n");
}
delay_ms(1000);
printf("请在窗口期喂狗!\r\n");
wwdg_init(0x7f,0x5f,WWDG_PRESCALER_8); //初始化窗口看门狗
while(1)
{
delay_ms(15);
HAL_WWDG_Refresh(&g_wwdg_handle); //喂狗
}
}