当前位置: 首页 > news >正文

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超出时间计算

T_{out}:WWDG超出时间

F_{wwdg}:WWDG的时钟源频率,36MHZ

4096:WWDG固定的预分频系数

2^{WDGTB}: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);
  }
}


 

相关文章:

  • 智能终端与边缘计算按章复习
  • Science Robotics:UCLA 贺曦敏团队综述自主软体机器人
  • npm install的原理
  • 【leetcode】3. 无重复字符的最长子串
  • JAVA学习 DAY2 java程序运行、注意事项、转义字符
  • logstash拉取redisStream的流数据,并存储ES
  • Kubernetes弃用Docker:技术演进与生态变革的深度解析
  • 5.2 HarmonyOS NEXT应用性能诊断与优化:工具链、启动速度与功耗管理实战
  • Tika Server:企业级文档内容解析的轻量级服务化方案
  • 发版前后的调试对照实践:用 WebDebugX 与多工具构建上线验证闭环
  • AI大模型学习三十三、HeyGem.ai 服务端(ubuntu)docker 安装 /客户端(win)分离部署
  • CentOS 7 如何安装llvm-project-10.0.0?
  • 使用Python和OpenCV实现图像识别与目标检测
  • 负载均衡LB》》HAproxy
  • 全球长序列高分辨率光合有效辐射(PAR)(1984-2018)
  • 三、元器件的选型
  • 水库大坝安全监测系统是什么?需要用到哪些设备?
  • 分布式协同自动化办公系统-工作流引擎-流程设计
  • LeetCode 2434.使用机器人打印字典序最小的字符串:贪心(栈)——清晰题解
  • VS Code使用 SSH 扩展连接主机出现失败的解决方案
  • 网站建设 代理/百度指数大数据
  • 学做预算网站/百度企业推广怎么收费
  • 做网站便宜还是app便宜/网页自动点击软件
  • 可以做淘宝推广的网站有哪些内容/长沙关键词快速排名
  • 简单的网站开发工具/网站流量排名查询工具
  • 南京发布最新通报/优化快速排名公司