基于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)

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

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

基于STM32F1的WDG (Watchdog)看门狗_第1张图片

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

基于STM32F1的WDG (Watchdog)看门狗_第2张图片

1.1  IWDG键寄存器

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

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

写入键寄存器的值 作用
OxCCCC 启用独立看门狗
OxAAAA IWDG_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}}

基于STM32F1的WDG (Watchdog)看门狗_第3张图片

对于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)

基于STM32F1的WDG (Watchdog)看门狗_第4张图片

2.1  工作特性

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

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

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

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

基于STM32F1的WDG (Watchdog)看门狗_第5张图片

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}^{}

基于STM32F1的WDG (Watchdog)看门狗_第6张图片

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的WDG (Watchdog)看门狗_第7张图片

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

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

基于STM32F1的WDG (Watchdog)看门狗_第8张图片

你可能感兴趣的:(STM32学习笔记,stm32,嵌入式硬件,单片机,c语言,物联网,mcu,proteus)