天天看点

STM32-窗口看门狗---WWDG

窗口看门狗—WWDG

1.基本介绍

独立看门狗是12位递减计数器,窗口看门狗是7位递减计数器。

独立看门狗没上限值,窗口看门狗有上限值(由用户设定)和固定下限值(0X40)。

窗口看门狗在上限值以上进行喂狗会产生复位,在下限值还未进行喂狗也会产生复位。故窗口看门狗一定要在上限值和下限值之间进行喂狗。

STM32-窗口看门狗---WWDG
1.1窗口看门狗时钟

窗口看门狗时钟来自PCLK1,挂接在APB1总线上,由RCC开启。最大频率为42M。

1.2WDG预分频器

PCLK1时钟经过预分频器分频后输入给计数器时钟。

分频因子通过WWDG_CFR的8:7设置分频因子,可设为0 、 1 、 2、 3。

分频后的计数器时钟为:CK_CNT=PCLK1/4096/(2^WDGTB)

PCLK1等于APB1时钟;

WDGTB为分频因子(0-3)

4096为固定值。

1.3计数器

计数器为7位递减计数器,故计数器最大值为0x7F。值放在WWDG_CR中的6:0位。故计数器的范围为0x7F-0x40。

为防止忘记进行喂狗,可开启提前唤醒中断。开启后当计数器计数到0x40时,进入中断。开启中断方式为WWDG_CFR位9EWI置1。

如果不用中断进行喂狗,也可以进行计算,在计算时间内进行喂狗。

Twwdg=(4096×2^WDGTB×(T[5:0]+1))/PCLK1;

Twwdg为窗口看门狗的超时时间,单位为ms。

PCLK1为APB1的时钟频率,最大42MHz。

WDGTB为窗口看门狗的预分频系数。

T[5:0]为窗口看门狗的计数器低6位。

若PCLK1为42MHz,则最大超时和最小超时时间如下图

STM32-窗口看门狗---WWDG
1.4看门狗配置寄存器(WWDG_CFR)

一般设置为窗口看门狗时间比实际程序运行时间稍大一些,就可在程序刚运行完后进行看门狗喂狗。

1.5系统复位信号

当超过窗口上限值喂狗或低于窗口下限值还未进行喂狗,并且WDGA位置为1(开启窗口看门狗)。将产生一个复位信号,系统复位。

2.相关寄存器

2.1中断结构体
typedef struct
{
  uint8_t NVIC_IRQChannel;//中断通道
  uint8_t NVIC_IRQChannelPreemptionPriority;//抢占优先级
  uint8_t NVIC_IRQChannelSubPriority;//子优先级
  FunctionalState NVIC_IRQChannelCmd;//中断使能
} NVIC_InitTypeDef;
           
2.2窗口看门狗结构体
typedef struct
{
  __IO uint32_t CR;   //看门狗控制寄存器,设置计数值及使能看门狗
  __IO uint32_t CFR;  //看门狗配置寄存器,设置窗口值上限,使能中断
  __IO uint32_t SR;   //状态寄存器,清除中断标志位
} WWDG_TypeDef;
           

3.配置步骤

3.1分步设置

(1)定义相关结构体

(2)开启开门狗时钟

(3)设置窗口值和分频数

WWDG_SetWindowValue(0x5f);//设置窗口值
	WWDG_SetPrescaler(WWDG_Prescaler_8);//设置分频值
           
//设定窗口值
void WWDG_SetWindowValue(uint8_t WindowValue)
{
  __IO uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_WWDG_WINDOW_VALUE(WindowValue));
  /* Clear W[6:0] bits */
  tmpreg = WWDG->CFR & CFR_W_MASK;
  /* Set W[6:0] bits according to WindowValue value */
  tmpreg |= WindowValue & (uint32_t) BIT_MASK;
  /* Store the new value */
  WWDG->CFR = tmpreg;
}
           
#define WWDG_Prescaler_1    ((uint32_t)0x00000000)
#define WWDG_Prescaler_2    ((uint32_t)0x00000080)
#define WWDG_Prescaler_4    ((uint32_t)0x00000100)
#define WWDG_Prescaler_8    ((uint32_t)0x00000180)
//设置分频数
/**
  * @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)
{
  uint32_t tmpreg = 0;
  /* Check the parameters */
  assert_param(IS_WWDG_PRESCALER(WWDG_Prescaler));
  /* Clear WDGTB[1:0] bits */
  tmpreg = WWDG->CFR & CFR_WDGTB_MASK;
  /* Set WDGTB[1:0] bits according to WWDG_Prescaler value */
  tmpreg |= WWDG_Prescaler;
  /* Store the new value */
  WWDG->CFR = tmpreg;
}
           

(4)初始化中断结构体

NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//窗口中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器
           

(5)设置计数器初始值并使能WWDG

WWDG_Enable(0x7f); //使能窗口看门狗并初始化计数器值,看门狗控制器寄存器WDGA置1
	WWDG_ClearFlag(); //清除窗口看门狗状态标志(这一句必须加上,否则进入不了中断)
           
//使能WWDG函数
void WWDG_Enable(uint8_t Counter)
{
  /* Check the parameters */
  assert_param(IS_WWDG_COUNTER(Counter));
  WWDG->CR = WWDG_CR_WDGA | Counter;
}
           
//清除看门狗状态标志函数
void WWDG_ClearFlag(void)
{
  WWDG->SR = (uint32_t)RESET;
}
           

(6)开启看门狗中断

//看门狗中断使能函数
void WWDG_EnableIT(void)
{
  *(__IO uint32_t *) CFR_EWI_BB = (uint32_t)ENABLE;
}
           

(7)编写看门狗中断函数

/*******************************************************************************
* 函 数 名         : WWDG_IRQHandler
* 函数功能		   : WWDG中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void WWDG_IRQHandler(void)
{
	WWDG_SetCounter(0x7f); //重新赋值
	WWDG_ClearFlag(); //清除窗口看门狗状态标志
}
           
3.2完整窗口看门狗初始化函数
/*******************************************************************************
* 函 数 名         : WWDG_Init
* 函数功能		   : WWDG初始化
					 窗口值是:0x5f
					 定时器计数值是:0x7f
					 预分频值是:8
					 窗口看门狗进入中断的频率计算公式是:PCLK1/(4096*2^pre)
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void WWDG_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //开启窗口看门狗的时钟
	WWDG_SetWindowValue(0x5f);//设置窗口值
	WWDG_SetPrescaler(WWDG_Prescaler_8);//设置分频值
	
	NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//窗口中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器
	
	WWDG_Enable(0x7f); //使能窗口看门狗并初始化计数器值
	WWDG_ClearFlag(); //清除窗口看门狗状态标志(这一句必须加上,否则进入不了中断)
	WWDG_EnableIT(); //开启中断
}

/*******************************************************************************
* 函 数 名         : WWDG_IRQHandler
* 函数功能		   : WWDG中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void WWDG_IRQHandler(void)
{
	WWDG_SetCounter(0x7f); //重新赋值
	WWDG_ClearFlag(); //清除窗口看门狗状态标志
}
           

讲解不到位的希望大家指出,有需要我讲解的部分,希望大家提出,我会出文档讲解。