一.WWDG简介
<1>.全称
Window watchdog,即窗口看门狗。
<2>本质
能产生系统复位信号和提前唤醒中断的计数器。
<3>特性
递减的计数器
- 当递减计数器值从0x40减到0x3F时复位(即T6位跳变成0);
- 计数器的值大于W[6:0]值时喂狗会复位;
- 提前唤醒中断(EWI):当递减计数器等于0x40时可产生。
喂狗:在窗口期内重装载计数器的值,防止复位。
<4>作用
作用:用于监测单片机程序运行时效是否精准,主要检测软件异常;
应用:需要精准监测程序运行时间的场合。
二.WWDG工作原理
注意:W[6:0]必须大于窗口下限制0x3F,否则无窗口期。
三.WWDG框图
四.WWDG寄存器
用于使能窗口看门狗工作,以及重装载计数器值(即喂狗)。
用于判断是否发生了WWDG提前唤醒中断。
五.WWDG超时时间计算
六.WWDG配置步骤
- WWDG工作参数初始化:HAL_WWDG_Init();
- WWDG Msp初始化:HAL_WWDG_MspInit() --- 配置NVIC、CLOCK等;
- 设置优先级,使能中断:HAL_NVIC_SetPriority()、HAL_NVIC_Enable();
- 编写中断服务函数:WWDG_IRQHandler() ---> HAL_WWDG_IRQHandler();
- 重定义提前唤醒回调函数:HAL_WWDG_EarlyWakeupCallback();
- 在窗口期内喂狗:HAL_WWDG_Refresh()。
七.编程实战:验证窗口看门狗功能(F1)
wwdg.c
#include "wwdg.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;
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)
{
LED0_TOGGLE();
}
wwdg.h
#ifndef _WWDG_H
#define _WWDG_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/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "wwdg.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
led_init(); /* 初始化LED */
usart_init(115200); /* 波特率设置为115200 */
wwdg_init(0X7F, 0X5F,WWDG_PRESCALER_8);
if(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST) != RESET)
{
printf("窗口看门狗复位\r\n");
__HAL_RCC_CLEAR_RESET_FLAGS();
}else
{
printf("外部复位\r\n");
}
delay_ms(1000);
printf("请在窗口期内喂狗\r\n\r\n");
while(1)
{
delay_ms(57);
HAL_WWDG_Refresh(&g_wwdg_handle);
}
}