32单片机——窗口看门狗

1、WWDG的简介

WWDG:Window watchdog,即窗口看门狗

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

WWDG产生复位信号的条件:

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

(2)计数器的值大于W6:0值时喂狗会复位

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

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

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

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

2、WWDG的工作原理

3、WWDG的框图

4、WWDG超出时间计算

:WWDG超出时间

:WWDG的时钟源频率,36MHZ

4096:WWDG固定的预分频系数

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

T5: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<窗口值≤W6: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);

}

}

相关推荐
Devlab6 小时前
LVGL设计大师——网页版anyui来了!!
嵌入式硬件·物联网·低代码·ui·iot
Dr.kangder9 小时前
嵌入式面试总结(十五)——异常处理
单片机·面试·职场和发展·系统架构·嵌入式
zlinear数据采集卡11 小时前
D223上位机C#开发实战:从帧解析到波形显示的完整实现
开发语言·arm开发·嵌入式硬件·fpga开发·开源·c#
ACP广源盛1392462567311 小时前
蚂蚁百灵 Ling‑3.0‑flash 开源 + 昇腾 0‑Day 原生适配@ACP#GSV9001E 在国产算力矩阵中的机会与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件
Rocktech_ruixun13 小时前
机器人端侧大模型部署对主板有哪些要求?瑞迅主控板分级方案对比
人工智能·嵌入式硬件·机器人
振南的单片机世界14 小时前
SysTick硬核拆解:既是HAL_Delay的“心跳”,也是RTOS的“节拍器”
arm开发·stm32·单片机·嵌入式硬件
Lzh编程小栈14 小时前
【嵌入式底层】SPI超透彻详解:通信原理、四线结构、四种模式、寄存器底层 + 面试全集
c语言·stm32·单片机·面试·职场和发展
Rocktech_ruixun14 小时前
机器人数据采集能力取决于什么?瑞迅科技RK3588/3576核心板方案深度解析
人工智能·嵌入式硬件·机器人
水果里面有苹果14 小时前
28-DRV8825PWPR步进电机驱动器
单片机
恒锐丰科技韩生15 小时前
率能 SS6625E|3.0~20V 单通道 H 桥直流电机驱动 SOP8 电子锁玩具机器人分享
嵌入式硬件·硬件工程