学习STM32入门窗口看门狗(WWDG)详解(五)笔记

一、WWDG介绍

全称:Windows watchdog,即窗口看门狗;

本质:能产生系统复位信号和提前唤醒中断的计数器;

特性

1、递减计数器;

2、产生复位信号的条件有两个:当递减计数器从0x40减至0x3F时会产生复位信号;当计数器的值大于W[6:0]值时,喂狗会产生复位信号。

3、提前唤醒中断(EWI):当递减计数器等于0x40时,会产生一个提前唤醒中断。

喂狗:在窗口期内重装载计数器的值,防止复位信号的产生;

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

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

二、WWDG工作原理

       产生复位的条件:1、当递减计数器的值小于0x40,(若看门狗被启动)则产生复位。2、 当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位。

       产生中断的条件:启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI)

三、WWDG工作原理图

四、WWDG相关寄存器

控制寄存器WWDG_CR

用于使能窗口看门狗工作,以及重装载计数器值(即喂狗)

          该寄存器只有低八位有效,其中 T[60]用来存储看门狗的计数器的值,随时更新的,每隔 (4096×2^ WDGTB[2:0]PCLK 个周期减 1。当该计数器的值从 0x40 变为 0x3F 的时候,将产 生看门狗复位。

        WDGA 位则是看门狗的激活位,该位由软件置 1,启动看门狗,并且一定要注意的是该位 一旦设置,就只能在硬件复位后才能清零了。

配置寄存器(WWDG_CFR

用于使能窗口看门狗提前唤醒中断,设置预分频系数,设置窗口上限值。

        该寄存器中的 EWI 位是提前唤醒中断,如果该位置 1,当递减计数器等于 0x40 时产生提 前唤醒中断,我们就可以及时喂狗以避免 WWDG 复位。因此,我们一般都会用该位来设置中 断,当窗口看门狗的计数器值减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中 断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在 进入中断后,必须在不大于 1 个窗口看门狗计数周期的时间(在 pclk1 频率为 36M WDGTB 0 的条件下,该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位!

状态寄存器(WWDG_SR

用于判断是否发生了WWDG提前唤醒中断。

该寄存器用来记录当前是否有提前唤醒的标志。该寄存器仅有位 0 有效,其他都是保留位。 当计数器值达到 0x40 时,此位由硬件置 1。它必须通过软件写 0 来清除。对此位写 1 无效。即 使中断未被使能,在计数器的值达到 0x40 的时候,此位也会被置 1

五、WWDG超时时间计算

六、WWDG配置步骤

(1)WWDG工作参数初始化: HAL_WWDG_Init()

(2)WWDG Msp初始化: HAL_WWDG_MspInit()配置NVIC、CLOCK等

(3)设置优先级,使能中断: HAL_NVIC_SetPriority()、 HAL_NVIC_EnableIRQ()

(4)编写中断服务函数:  WWDG_IRQHandler()àHAL_WWDG_IRQHandler

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

(6)在窗口期内喂狗:HAL_WWDG_Refresh()

相关HAL库函数介绍

1.HAL_WWDG_Init 函数

WWDG 的初始化函数,其声明如下:

HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg);

形参 1 是 WWDG 句柄,WWDG_HandleTypeDef 结构体类型,其定义如下:

typedef struct 
{ 
 WWDG_TypeDef *Instance; /* WWDG 寄存器基地址 */ 
 WWDG_InitTypeDef Init; /* WWDG 初始化参数 */ 
}WWDG_HandleTypeDef; 

1)Instance:指向 WWDG 寄存器基地址。 2)Init:WWDG 初始化结构体,用于配置计数器的相关参数。 WWDG_InitTypeDef 这个结构体类型定义如下

typedef struct 
{ 
 uint32_t Prescaler; /* 预分频系数 */ 
 uint32_t Window; /* 窗口值 */ 
 uint32_t Counter; /* 计数器值 */ 
 uint32_t EWIMode; /* 提前唤醒中断使能 */ 
} WWDG_InitTypeDef; 

1) Prescaler:预分频系数,WWDG_PRESCALER_1\ WWDG_PRESCALER_2\ WWDG_PRESCALER_4\ WWDG_PRESCALER_8 四个值,分别表示 1~8 分频。

2)Window:窗口值,即上限值。

3)Counter:计数器值,用于保存要设置计数器的值。

4)EWIMode:提前唤醒中断使能。

2. HAL_WWDG_Refresh 函数

HAL_WWDG_Refresh 函数是窗口看门狗的喂狗函数。其声明如下:

HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg); 

函数描述: 该函数实际就是往 CR 寄存器重写 Counte 这个预先保存的计数器值。

函数形参: 形参 1 是 WWDG_HandleTypeDef 结构体指针类型的 WWDG 句柄。

七、相关代码

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/wwdg/wwdg.h"
#include "./BSP/led/led.h"
int main(void)
{
    HAL_Init();                              /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);      /* 设置时钟, 72Mhz */
    delay_init(72);                          /* 延时初始化 */
    led_init();                              /* LED初始化 */
    led0(0);                                 /* LED点亮 */
    delay_ms(300);                           /* 延时 300ms*/
    wwdg_init(0X7F,0X5F,WWDG_PRESCALER_8 );  /* 计数值为 7f,窗口值为 5f,分频数为 8 */
    while(1)
    { 
       led0(1);
    }
}

wwdg.c

#include "./BSP/wwdg/wwdg.h"
#include "./BSP/led/led.h"
WWDG_HandleTypeDef wwdg_handler;
 
//窗口看门狗初始化函数
void wwdg_init(uint8_t tr,uint8_t wr,uint32_t fprer )
{
   wwdg_handler.Instance= WWDG;                 //设置寄存器基地址;
   wwdg_handler.Init.Counter= tr;               //设置计数器的值;
   wwdg_handler.Init.Prescaler= fprer;          //设置预分频系数;
   wwdg_handler.Init.Window= wr;                //设置窗口值;
   wwdg_handler.Init.EWIMode=WWDG_EWI_ENABLE;   //设置使能窗口看门狗唤醒中断; 
        HAL_WWDG_Init(&wwdg_handler);
}
//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(&wwdg_handler);//HAL库函数中断服务函数,会进行回调函数
}
 
//WWDG提前唤醒函数
 void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
 {
         HAL_WWDG_Refresh(&wwdg_handler);
     HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);//led1的状态发生转变。
 }
 

led.c

#include "./BSP/led/led.h"
 
void led_init(void)
{
   GPIO_InitTypeDef led_Init0;
    __HAL_RCC_GPIOB_CLK_ENABLE();
    led_Init0.Mode= GPIO_MODE_OUTPUT_PP;
    led_Init0.Pin=GPIO_PIN_5;
    led_Init0.Pull=GPIO_PULLUP;
    led_Init0.Speed=GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &led_Init0);
    
    GPIO_InitTypeDef led_Init1;
    __HAL_RCC_GPIOE_CLK_ENABLE();
    led_Init1.Mode= GPIO_MODE_OUTPUT_PP;
    led_Init1.Pin=GPIO_PIN_5;
    led_Init1.Pull=GPIO_PULLUP;
    led_Init1.Speed=GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOE, &led_Init1);
    
    
     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_SET);
     HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5, GPIO_PIN_SET);
}
 
 
void led0(uint8_t i)
{
if(i==1)
{
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_SET);
}
else
     HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_RESET);
   
}
 
 

  • 44
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值