基于STM32F1的WDG (Watchdog)看门狗

目录

1.  独立看门狗(IWDG)

1.1  IWDG键寄存器

1.2  IWDG超时时间

1.3   IWDG程序设计

1.3.1  写使能控制

1.3.2  写预分频器

1.3.3  写重装值

1.3.4  喂狗

1.3.5  启动独立看门狗

1.3.6  获取标志位状态

1.3.7  代码片段

2.  窗口看门狗(WWDG)

2.1  工作特性

2.2  WWDG超时时间

2.3  WWDG程序设计

2.3.1  恢复缺省配置

2.3.2  写入预分频器

2.3.3  写入窗口值

2.3.4  使能中断

2.3.5  喂狗

2.3.6  使能窗口看门狗

2.3.7  获取标志位

2.3.8  清除标志位

2.3.7  代码片段

3.  IWDG和WWDG对比


        看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号STM32内置两个看门狗。

独立看门狗(IWDG) :独立工作,对时间精度要求较低

窗口看门狗(WWDG) : 要求看门狗在精确计时窗口起作用

1.  独立看门狗(IWDG)

        首先,我们可以类比定时中断的时基单元。

        时基单元由预分频器、计数器和重装载寄存器组成。

        假如72MHz的输入时钟,经过预分频器(这里假如2分频),则驱动时钟为72/2=36,在计数器会产生自增和自减,看门狗是进行自减,自减到0,定时器产生更新事件和中断,看门狗则进行复位。

1.1  IWDG键寄存器

        键寄存器本质上是控制寄存器,用于控制硬件电路的工作。

        在可能存在干扰的情况下,一般通过在整个键寄存器写入特定值来代替控制寄存器写入一位的功能,以降低硬件电路受到干扰的概率。

写入键寄存器的值作用
OxCCCC启用独立看门狗
OxAAAAIWDG_RLR中的值重新加载到计数器(喂狗)
0x5555

解除IWDG_PR和IWDG_RLR的写保护

0x5555之外的其他值启用IWDG_PR和IWDG_RLR的写保护

1.2  IWDG超时时间

超时时间:T^{_{IWDG}}=T^{_{LSI}}*PR预分频系数*(RL+1)

其中:T^{_{LSI}}=1/F^{_{LSI}}

对于T^{_{LSI}}=1/F^{_{LSI}}=1/40KHz=0.025ms。

1.3   IWDG程序设计

1.3.1  写使能控制

void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);

定义:

/**
  * @brief  Enables or disables write access to IWDG_PR and IWDG_RLR registers.
  * @param  IWDG_WriteAccess: new state of write access to IWDG_PR and IWDG_RLR registers.
  *   This parameter can be one of the following values:
  *     @arg IWDG_WriteAccess_Enable: Enable write access to IWDG_PR and IWDG_RLR registers
  *     @arg IWDG_WriteAccess_Disable: Disable write access to IWDG_PR and IWDG_RLR registers
  * @retval None
  */
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess)
{
  /* Check the parameters */
  assert_param(IS_IWDG_WRITE_ACCESS(IWDG_WriteAccess));
  IWDG->KR = IWDG_WriteAccess;
}
#define IWDG_WriteAccess_Enable     ((uint16_t)0x5555)
#define IWDG_WriteAccess_Disable    ((uint16_t)0x0000)
#define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \
                                      ((ACCESS) == IWDG_WriteAccess_Disable))

1.3.2  写预分频器

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

        就是写DR寄存器

定义:

/**
  * @brief  Sets IWDG Prescaler value.
  * @param  IWDG_Prescaler: specifies the IWDG Prescaler value.
  *   This parameter can be one of the following values:
  *     @arg IWDG_Prescaler_4: IWDG prescaler set to 4
  *     @arg IWDG_Prescaler_8: IWDG prescaler set to 8
  *     @arg IWDG_Prescaler_16: IWDG prescaler set to 16
  *     @arg IWDG_Prescaler_32: IWDG prescaler set to 32
  *     @arg IWDG_Prescaler_64: IWDG prescaler set to 64
  *     @arg IWDG_Prescaler_128: IWDG prescaler set to 128
  *     @arg IWDG_Prescaler_256: IWDG prescaler set to 256
  * @retval None
  */
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler)
{
  /* Check the parameters */
  assert_param(IS_IWDG_PRESCALER(IWDG_Prescaler));
  IWDG->PR = IWDG_Prescaler;
}

1.3.3  写重装值

void IWDG_SetReload(uint16_t Reload);

        就是写RLR寄存器

定义:

/**
  * @brief  Sets IWDG Reload value.
  * @param  Reload: specifies the IWDG Reload value.
  *   This parameter must be a number between 0 and 0x0FFF.
  * @retval None
  */
void IWDG_SetReload(uint16_t Reload)
{
  /* Check the parameters */
  assert_param(IS_IWDG_RELOAD(Reload));
  IWDG->RLR = Reload;
}

1.3.4  喂狗

void IWDG_ReloadCounter(void);

        重新装载寄存器

定义:

/**
  * @brief  Reloads IWDG counter with value defined in the reload register
  *   (write access to IWDG_PR and IWDG_RLR registers disabled).
  * @param  None
  * @retval None
  */
void IWDG_ReloadCounter(void)
{
  IWDG->KR = KR_KEY_Reload;
}

在键寄存器写入:KR_KEY_Reload

/* KR register bit mask */
#define KR_KEY_Reload    ((uint16_t)0xAAAA)
#define KR_KEY_Enable    ((uint16_t)0xCCCC)

1.3.5  启动独立看门狗

void IWDG_Enable(void);
/**
  * @brief  Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled).
  * @param  None
  * @retval None
  */
void IWDG_Enable(void)
{
  IWDG->KR = KR_KEY_Enable;
}

1.3.6  获取标志位状态

FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);

1.3.7  代码片段

#include "stm32f10x.h"                  // Device header
int main(void)
{
	
	
	/*IWDG初始化*/
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);	//独立看门狗写使能
	IWDG_SetPrescaler(IWDG_Prescaler_16);			//设置预分频为16
	IWDG_SetReload(2499);							//设置重装值为2499,独立看门狗的超时时间为1000ms
	IWDG_ReloadCounter();							//重装计数器,喂狗
	IWDG_Enable();									//独立看门狗使能
	
	while (1)
	{
		
		IWDG_ReloadCounter();						//重装计数器,喂狗
		
	}
}

2.  窗口看门狗(WWDG)

2.1  工作特性

        递减计数器T[6:0]的值小于0x40时,WWDG产生复位;

        递减计数器T[6:0]在窗口W[6:0]外被重新装载时,WWDG产生复位;

        递减计数器T[6:0]等于0x40时可以产生早期唤醒中断(EWI),用于重装载计数器以避免WWDG复位;

        定期写入WWDG_CR寄存器(喂狗)以避免WWDG复位。

2.2  WWDG超时时间

超时时间(喂狗的最晚时间):     

T_{WWDG}^{}=T{_{PCLK1}}^{}×× 4096× WDGTB预分频系数× (T[5:0] + 1)

窗口时间(喂狗的最早时间):  

T_{WIN }^{}=   T{_{PCLK1}}^{}×× 4096 × WDGTB预分频系数 × (T[5:0] - W[5:0])

其中:

T{_{PCLK1}}^{}× = 1 / F_{PCLK1}^{}

2.3  WWDG程序设计

2.3.1  恢复缺省配置

void WWDG_DeInit(void);

2.3.2  写入预分频器

void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);

2.3.3  写入窗口值

void WWDG_SetWindowValue(uint8_t WindowValue);

2.3.4  使能中断

void WWDG_EnableIT(void);

2.3.5  喂狗

void WWDG_SetCounter(uint8_t Counter);

2.3.6  使能窗口看门狗

void WWDG_Enable(uint8_t Counter);

2.3.7  获取标志位

FlagStatus WWDG_GetFlagStatus(void);

2.3.8  清除标志位

void WWDG_ClearFlag(void);

2.3.7  代码片段

#include "stm32f10x.h"                  // Device header

int main(void)
{
	
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);	//开启WWDG的时钟
	
	/*WWDG初始化*/
	WWDG_SetPrescaler(WWDG_Prescaler_8);			//设置预分频为8
	WWDG_SetWindowValue(0x40 | 21);					//设置窗口值,窗口时间为30ms
	WWDG_Enable(0x40 | 54);							//使能并第一次喂狗,超时时间为50ms
	
	while (1)
	{

		WWDG_SetCounter(0x40 | 54);					//重装计数器,喂狗
	}
}

3.  IWDG和WWDG对比

STM32F1之RTC实时时钟(Unix时间戳)-CSDN博客

BKP备份寄存器、RTC实时时钟-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值