STM32窗口看门狗(警犬)

结合上篇文章食用更佳。
传送门:STM32独立看门狗(宠物狗)

二、窗口看门狗

独立看门狗主要用来监测硬件,窗口看门狗主用来监测软件。

窗口看门狗通常被用来监测,由外部干扰或不可预见的逻辑条件(程序)造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。如果在递减计数器达到窗口寄存器值之前刷新控制寄存器中的7位递减计数器值,也会产生MCU复位。这意味着必须在限定的时间窗口内刷新计数器(即喂狗)。

窗口看门狗 (WWDG) 时钟由 APB1 时钟经预分频后提供,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。

1、主要特性
窗口看门狗跟独立看门狗一样,也是一个递减计数器不断的往下递减计数,当减到一个固定值 0X40 时还不喂狗的话,产生复位, 这个值叫窗口的下限, 是固定的值,不能改变。这个是跟独立看门狗类似的地方,不同的地方是窗口看门狗的计数器的值在减到某一个数之前喂狗的话也会产生复位,这个值叫窗口的上限,上限值由用户独立设置。

窗口看门狗计数器的值必须在上窗口和下窗口之间才可以喂狗,这就是窗口看门狗中窗口两个字的含义,如果在窗口之外,那么会导致CPU复位。

在这里插入图片描述

2、功能说明
如果激活看门狗(WWDG_CR 寄存器中的 WDGA 位置 1),则当 7 位递减计数器(T[6:0]位)从 0x40 滚动到 0x3F(T6 已清零)时会引发复位。当计数器值大于窗口寄存器中所存储的值时,如果软件重载计数器,则会产生复位。

3、库函数接口

a.设置窗口看门狗分频值

  • @brief Sets the WWDG Prescaler.
  • @param WWDG_Prescaler: specifies the WWDG Prescaler.
  • This parameter can be one of the following values:
  • @arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1/4096)/1
  • @arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1/4096)/2
  • @arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1/4096)/4
  • @arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1/4096)/8
  • @retval None
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)

b.设置窗口看门狗窗口值

  • @brief Sets the WWDG window value.
  • @param WindowValue: specifies the window value to be compared to the downcounter.
  • This parameter value must be lower than 0x80.
  • @retval None
void WWDG_SetWindowValue(uint8_t WindowValue)

c.窗口看门狗使能

  • @brief Enables WWDG and load the counter value.
  • @param Counter: specifies the watchdog counter value.
  • This parameter must be a number between 0x40 and 0x7F (to prevent generating
  • an immediate reset)
void WWDG_Enable(uint8_t Counter)

d.窗口看门清除中断标志位

  • @brief Clears Early Wakeup interrupt flag.
void WWDG_ClearFlag(void)

e.窗口看门狗中断使能

  • @brief Enables the WWDG Early Wakeup interrupt(EWI).
  • @note Once enabled this interrupt cannot be disabled except by a system reset.
void WWDG_EnableIT(void)

喂狗的时候,最好是在计数值减到ox40的时候,就触发中断喂狗

#练习
编写窗口看门狗程序,led的程序可以看上篇独立看门狗的文章,

#include "stm32f4xx.h"
#include "./led/bsp_led.h"
#include "stdio.h"


static void Delay(__IO u32 nCount); 
static GPIO_InitTypeDef  	GPIO_InitStructure;
static USART_InitTypeDef 	USART_InitStructure;
static NVIC_InitTypeDef 	NVIC_InitStructure;		


void iwdg_config(void)
{
    
    
	
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//窗口看门狗NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//窗口看门狗中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
	NVIC_Init(&NVIC_InitStructure);												//根据指定的参数初始化NVIC寄存器
	
	//使能窗口看门狗时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);

	//设置看门狗的时钟,45MHZ/4096/8=1373HZ
	WWDG_SetPrescaler(IWDG_Prescaler_8);

	//设置窗口上限值,最大是0x80
	WWDG_SetWindowValue(80);

	/* 设置看门狗的最大计数值*/
	WWDG_Enable(127);

	//清空提前唤醒中断标志位
	WWDG_ClearFlag();

	//使能提前唤醒中断
	WWDG_EnableIT();
	
	  /* 检查是否复位 */
   if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
   {
    
    
    /* IWDGRST flag set */
	LED_RED;//复位亮红灯
    /* Clear reset flags */
     RCC_ClearFlag();
   }
  else
  {
    
    
   /* IWDGRST flag is not set */
    LED_GREEN;//成功喂狗亮绿灯
  }


	
}

int main(void)
{
    
    
	/* LED 端口初始化 */
	LED_GPIO_Config();	 
	Delay(0X8FFFFF);	
	iwdg_config();
	while(1)                            
	{
    
    	   

	}
}

static void Delay(__IO uint32_t nCount)	 //简单的延时函数
{
    
    
	for(; nCount != 0; nCount--);
}
void WWDG_IRQHandler(void)
{
    
    	
	if(WWDG_GetFlagStatus()== SET)
	{
    
    
		//重新设置计数值,也就是执行喂狗动作
		WWDG_SetCounter(127);//这里只能用这个函数进行喂狗
	//清空提前唤醒中断标志位
		WWDG_ClearFlag();
	}
	
}

/*********************************************END OF FILE**********************/

#思考
如果在while(1)循环体一直重设窗口看门狗值,系统会不会复位?
回答:会复位,因为是在窗口值外面的计数值进行了喂狗,所以会导致CPU进行复位操作,标准的喂狗动作放在DDWG_IRQHandler中断中。

而且,独立看门狗和窗口看门狗同时使用的时候,窗口看门狗的优先级一般设置为00最高,定时器的优先级要低于窗口看门狗的优先级,如果反过来的话,会导致窗口看门狗无法抢占优先级而导致CPU复位。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ABCisCOOL/article/details/115082884