当前位置: 首页 > 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);
  }
}


 

http://www.lqws.cn/news/179209.html

相关文章:

  • 五子棋测试用例
  • go语言学习 第6章:错误处理
  • 浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的
  • Java逻辑运算符常见错误分析与规避指南
  • 03 mysql 的环境搭建
  • 服务器磁盘空间被Docker容器日志占满处理方法
  • 服务器信任质询
  • 什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
  • 服务器出现故障怎么办?快速排查与解决方法
  • PostgreSQL 的扩展pg_freespacemap
  • Linux操作系统之进程(五):初识地址空间
  • Edge(Bing)自动领积分脚本部署——基于python和Selenium(附源码)
  • 七、数据库的完整性
  • Codeforces EDU Round 179 A~D
  • PDF转Markdown/JSON软件MinerU最新1.3.12版整合包下载
  • HarmonyOS运动语音开发:如何让运动开始时的语音播报更温暖
  • Redis 主从 + 哨兵集群部署
  • 【HarmonyOS 5】出行导航开发实践介绍以及详细案例
  • 《深度探秘:Java构建Spark MLlib与TensorFlow Serving混合推理流水线》
  • 麒麟系统使用-进行.NET开发
  • 电脑开不了机,主板显示67码解决过程
  • vue项目引入tailwindcss
  • 华为 “一底双长焦” 专利公布,引领移动影像新变革
  • 在 Windows 系统上运行 Docker 容器中的 Ubuntu 镜像并显示 GUI
  • 【信息系统项目管理师-论文真题】2025上半年(第一批)论文详解(包括解题思路和写作要点)
  • 基于端到端深度学习模型的语音控制人机交互系统
  • Mysql主从复制与读写分离
  • BugKu Web渗透之需要管理员
  • PHP语言核心技术全景解析
  • [BJDCTF2020]Easy MD5 1