STM32
直播中

杜喜喜

7年用户 1492经验值
私信 关注
[问答]

如何启用STM32的窗口看门狗呢

独立看门狗WWDG的主要特性有哪些?
独立看门狗WWDG的功能有哪些?

如何启用STM32的窗口看门狗呢?

回帖(1)

h1654155275.5697

2021-9-8 15:58:03
  简介:
  独立看门狗限制喂狗时间在0-x内,x由相关寄存器决定。喂狗时间不能过晚。
  而窗口看门狗喂狗时间有个上下限的范围(称为窗口),课以通过设定相关的寄存器,设定其上限时间(下限固定)。喂狗时间不能过晚也不能过早。
  1.WWDG主要特性
  ● 可编程的自由运行递减计数器 ● 条件复位 ─ 当递减计数器的值小于0x40,(若看门狗被启动)则产生复位。 ─
  当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位。
  ● 如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可 以被用于重装载计数器以避免WWDG复位
  2.WWDG功能描述
  如果看门狗被启动(WWDG_CR寄存器中的WDGA位被置’1’), 并且当7位(T[6:0])递减计数器从0x40翻转到0x3F(T6位清零)时,则产生一个复位。如果软件在计数器值大于窗口寄存器中的数值时重新装载计数器,将产生一个复位。
  看门狗框图
  
  应用程序在正常运行过程中必须定期地写入WWDG_CR寄存器以防止MCU发生复位。只有当计数器值小于窗口寄存器的值时,才能进行写操作。储存在WWDG_CR寄存器中的数值必须在 0xFF和0xC0之间:
  ● 启动看门狗
  在系统复位后,看门狗总是处于关闭状态,设置WWDG_CR寄存器的WDGA位能够开启看 门狗,随后它不能再被关闭,除非发生复位。
  ●控制递减计数器 递减计数器处于自由运行状态,即使看门狗被禁止,递减计数器仍继续递减计数。当看门狗被启用时,T6位必须被设置,以防止立即产生一个复位。
  T[5:0]位包含了看门狗产生复位之前的计时数目;复位前的延时时间在一个最小值和一个最大值之间变化,这是因为写入WWDG_CR寄存器时,预分频值是未知的。 配置寄存器(WWDG_CFR) 中包含窗口的上限值:要避免产生复位,递减计数器必须在其值 小于窗口寄存器的数值并且大于0x3F时被重新装载,0描述了窗口寄存器的工作过程。
  另一个重装载计数器的方法是利用早期唤醒中断(EWI)。设置WWDG_CFR寄存器中的WEI 位开启该中断。当递减计数器到达0x40时,则产生此中断,相应的中断服务程序(ISR)可以用来加载计数器以防止WWDG复位。在WWDG_SR寄存器中写’0’可以清除该中断。
  窗口看门狗时序图
  
  3.寄存器描述
  3.1.控制寄存器(WWDG_CR)
  
  3.2.配置寄存器(WWDG_CFR)
  
  3.3. 状态寄存器(WWDG_SR)
  
  介绍要如何启用 STM32 的窗口看门狗。这里我们介绍库函数中用中断的方式来喂狗的方法。
  1)使能 WWDG 时钟
  WWDG 不同于 IWDG,IWDG 有自己独立的 40Khz 时钟,不存在使能问题。而 WWDG使用的是 PCLK1 的时钟,需要先使能时钟。方法是:
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 时钟使能
  2)设置窗口值和分频数
  void WWDG_SetWindowValue(uint8_t WindowValue);
  
  3.用来设置看门狗的分频值。
  void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
  
  
  3)开启 WWDG 中断并分组
  开启 WWDG 中断的函数为:
  WWDG_EnableIT(); //开启窗口看门狗中断
  
  4) 设置计数器初始值并使能看门狗
  void WWDG_Enable(uint8_t Counter);//该函数既设置了计数器初始值,同时使能了窗口看门狗。
  
  5) 编写中断服务函数
  在最后,还是要编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当窗口看门狗计数器值减到 0X3F 的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存器的 EWIF 位清空。
  4.示例代码
  .c
  include “WWDG.h”
  #include “led.h”//保存WWDG计数器的设置值,默认为最大。 u8 WWDG_CNT=0x7f; //初始化窗口看门狗
  //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer)。 void WWDG_NVIC_Init()
  {
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
  //WWDG中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占2,子优先级3,组2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  //抢占2,子优先级3,组2
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  NVIC_Init(&NVIC_InitStructure);//NVIC初始化}void WWDG_Init(u8 tr,u8 wr,u32 fprer)
  {
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能
  WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
  WWDG_SetPrescaler(fprer);设置IWDG预分频值
  WWDG_SetWindowValue(wr);//设置窗口值 ,指定的窗口值。该参数取值必须在 0x40 与 0x7F 之间
  WWDG_Enable(WWDG_CNT);
  // 使能 WWDG 并装入计数器值(1) Counter:指定看门狗计数器值。该参数取值必须在 0x40 与 0x7F 之间。
  WWDG_ClearFlag();//清除提前唤醒中断标志位
  WWDG_NVIC_Init();//初始化窗口看门狗 NVIC
  WWDG_EnableIT(); //开启窗口看门狗中断} //重设置WWDG计数器的值void WWDG_Set_Counter(u8 cnt)
  {
  WWDG_Enable(cnt);//使能看门狗 , 设置 counter 。
  }
  //窗口看门狗中断服务程序void WWDG_IRQHandler(void)
  //当计数器值到达0x40之后,执行中断服务函数
  {
  WWDG_SetCounter(WWDG_CNT);
  //当禁掉此句后,窗口看门狗将产生复位 设置 WWDG 计数器值
  WWDG_ClearFlag();
  //清除提前唤醒中断标志位
  GPIOE-》ODR^= 0X1《《5;
  //LED状态翻转
  }
  .h
  #ifndef _WWDG_H_
  #define _WWDG_H_
  #include “stm32f10x.h”
  void WWDG_Init(u8 tr,u8 wr,u32 fprer);
  void WWDG_Set_Counter(u8 cnt);
  #endif
举报

更多回帖

发帖
×
20
完善资料,
赚取积分