32单片机——窗口看门狗

1、WWDG的简介

WWDG:Window watchdog,即窗口看门狗

窗口看门狗本质上是能产生系统复位信号和提前唤醒中断的递减计数器

WWDG产生复位信号的条件:

(1)当递减计数器值从0x40减到0x3F时复位(即T6位跳变到0)

(2)计数器的值大于W[6:0]值时喂狗会复位

(3)提前唤醒中断(EWI):当递减计数器等于0x40时可产生

喂狗:在窗口期(W[6:0]值~0x40)内重装载计数器的值,防止复位

作用:用于监测单片机程序运行时效是否精准,主要检测软件异常

应用:需要精准检测程序运行时间的场合

2、WWDG的工作原理

3、WWDG的框图

4、WWDG超出时间计算

:WWDG超出时间

:WWDG的时钟源频率,36MHZ

4096:WWDG固定的预分频系数

:wwDG_CFR寄存器设置的预分频系数值

T[5:0]:WWDG计数器低6位

5、WWDG的配置步骤

(1)WWDG工作参数初始化

HAL_WWDG_Init();
HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);
{

WWDG_TypeDef *Instance; /* 寄存器基地址 */

WWDG_InitTypeDef Init; /* WWDG必需参数 */

#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)

void (* EwiCallback)(struct __WWDG_HandleTypeDef *hwwdg);

void (* MspInitCallback)(struct __WWDG_HandleTypeDef *hwwdg);

#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */

} WWDG_HandleTypeDef;
typedef struct

{

uint32_t Prescaler; /* 预分频系数 */

uint32_t Window; /* 0x3f<窗口值≤W[6:0] */

uint32_t Counter; /* 计数器值:0x40~0x7F */

uint32_t EWIMode ; /* 提前唤醒中断使能 */

} WWDG_InitTypeDef;

Prescaler的参数如下所示:

#define WWDG_PRESCALER_1 0x00000000u

/* WWDG计数器时钟=(PCLK1/4096)/1 */

#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0

/*!< WWDG计数器时钟=(PCLK1/4096)/2 */

#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1

/*!< WWDG计数器时钟=(PCLK1/4096)/4 */

#define WWDG_PRESCALER_8 (WWDG_CFR_WDGTB_1 | WWDG_CFR_WDGTB_0) /* WWDG计数器时钟=(PCLK1/4096)/8 */

EWIMode的参数如下所示:

#define WWDG_EWI_DISABLE 0x00000000u /* EWI禁用 */

#define WWDG_EWI_ENABLE WWDG_CFR_EWI /* EWI启用 */

(2)WWDG的Msp初始化

HAL_WWDG_MspInit();
__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg);

(3)设置优先级,使能中断

HAL_NVIC_SetPriority();

在32单片机------外部中断_32中断-CSDN博客中解释过

(4)编写中断服务函数

WWDG_IRQHandler(); //设置在startup_stm32f103xe.s中

HAL_WWDG_IRQHandler(); //中断公共处理函数
void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)

{

/* Check if Early Wakeup Interrupt is enable */

if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)

{

/* Check if WWDG Early Wakeup Interrupt occurred */

if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)

{

/* Clear the WWDG Early Wakeup flag */

__HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);

#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)

/* Early Wakeup registered callback */

hwwdg->EwiCallback(hwwdg);

#else

/* Early Wakeup callback */

HAL_WWDG_EarlyWakeupCallback(hwwdg);

#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */

}

}

}

(5)重定义提前唤醒回调函数

HAL_WWDG_EarlyWakeupCallback();

(6)在窗口期内喂狗

HAL_WWDG_Refresh();
HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)

{

/* Write to WWDG CR the WWDG Counter value to refresh with */

WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter));

/* Return function status */

return HAL_OK;

}

6、例子

先点亮LED0延时300ms后,初始化窗口看门狗,进入死循环,关闭LED0。然后等待窗口看门狗中断的到来,在中断里面,喂狗,并执行LED1的翻转操作。我们将通过LED0来指示STM32F1是否被复位了,如果被复位了就会点亮300ms。LED1用来指示中断喂狗,每次中断喂狗翻转一次。

wwdg.h

#ifndef _WWDG_H

#define _WWDG_H

#include "./SYSTEM/sys/sys.h"

#include "./SYSTEM/delay/delay.h"

//wwdg初始化

/*

参数1:定时器初始值

参数2:窗口值

参数3:预分频系数

*/

void wwdg_init(uint8_t tr,uint8_t wr,uint8_t prer);

#endif

wwdg.c

#include "./BSP/WWDG/wwdg.h"
WWDG_HandleTypeDef wwdg_handle; //wwdg句柄

void wwdg_init(uint8_t tr,uint8_t wr,uint8_t prer){

//初始化wwdg的工作参数

wwdg_handle.Instance=WWDG; //寄存器基地址

wwdg_handle.Init.Counter=tr; //计数器值

wwdg_handle.Init.EWIMode=WWDG_EWI_ENABLE; //提前唤醒中断使能

wwdg_handle.Init.Prescaler=prer; //预分频系数

wwdg_handle.Init.Window=wr; //窗口值

HAL_WWDG_Init(&wwdg_handle);

}

//窗口看门狗的Msp回调:一般用来设置GPIO、NVIC、CLOCK

void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg){

__HAL_RCC_WWDG_CLK_ENABLE(); //使能时钟

HAL_NVIC_SetPriority(WWDG_IRQn,0,0); //设置优先级

HAL_NVIC_EnableIRQ(WWDG_IRQn); //使能提前唤醒中断

}

//窗口看门狗提前唤醒中断的服务函数

void WWDG_IRQHandler(void){

HAL_WWDG_IRQHandler(&wwdg_handle); //中断公共处理函数

}

//提前唤醒中断的回调函数

//在此函数内写中断逻辑代码

void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg){

if(hwwdg->Instance==WWDG){

//喂狗

HAL_WWDG_Refresh(hwwdg);

//HAL_WWDG_Refresh(&wwdg_handle); //效果同上

}

}

main.c

#include "./SYSTEM/delay/delay.h"

#include "./SYSTEM/usart/usart.h"

#include "./BSP/LED/led.h"

#include "./BSP/BEEP/beep.h"

#include "./BSP/KEY/key.h"

#include "./BSP/WWDG/wwdg.h"

int main(void){

HAL_Init();

sys_stm32_clock_init(RCC_PLL_MUL9); //设置系统时钟

delay_init(72);

led_init();

beep_init();

key_init();

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);

delay_ms(100);

wwdg_init(0x7f,0x5f,WWDG_PRESCALER_8); //初始化wwdg

while (1){

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);

}

}

相关推荐
CODECOLLECT2 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen3 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠6 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_6 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技8 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计8 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
小龙报9 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业9 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能9 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
czwxkn10 小时前
4STM32(stdl)TIM定时器
stm32·单片机·嵌入式硬件