00. 目录
文章目录
01. WDG概述
-
WDG(Watchdog)看门狗
-
看门狗可以监控程序的运行状态,当程序因为设计漏洞、硬件故障、电磁干扰等原因,出现卡死或跑飞现象时,看门狗能及时复位程序,避免程序陷入长时间的罢工状态,保证系统的可靠性和安全性
-
看门狗本质上是一个定时器,当指定时间范围内,程序没有执行喂狗(重置计数器)操作时,看门狗硬件电路就自动产生复位信号
-
STM32内置两个看门狗
独立看门狗(IWDG):独立工作,对时间精度要求较低
窗口看门狗(WWDG):要求看门狗在精确计时窗口起作用
02. 独立看门狗相关API
2.1 IWDG_WriteAccessCmd
/**
* @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)
功能:
使能或者失能对寄存器 IWDG_PR 和 IWDG_RLR 的写操作
参数:
IWDG_WriteAccess:对寄存器 IWDG_PR 和 IWDG_RLR 的写操作的新状态
返回值:
无
2.2 IWDG_SetPrescaler
/**
* @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)
功能:
设置 IWDG 预分频值
参数:
IWDG_Prescaler:IWDG 预分频值
返回值:
无
2.3 IWDG_SetReload
/**
* @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)
功能:
设置 IWDG 重装载值
参数:
IWDG_Reload:IWDG 重装载值
返回值:
无
2.4 IWDG_ReloadCounter
/**
* @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 重装载寄存器的值重装载 IWDG 计数器
参数:
无
返回值:
无
2.5 IWDG_Enable
/**
* @brief Enables IWDG (write access to IWDG_PR and IWDG_RLR registers disabled).
* @param None
* @retval None
*/
void IWDG_Enable(void)
功能:
使能 IWDG
参数:
无
返回值:
无
2.6 IWDG_GetFlagStatus
/**
* @brief Checks whether the specified IWDG flag is set or not.
* @param IWDG_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg IWDG_FLAG_PVU: Prescaler Value Update on going
* @arg IWDG_FLAG_RVU: Reload Value Update on going
* @retval The new state of IWDG_FLAG (SET or RESET).
*/
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG)
功能:
检查指定的 IWDG 标志位被设置与否
参数:
IWDG_FLAG:待检查的 I2C 标志位
返回值:
IWDG_FLAG 的新状态(SET 或者 RESET)
2.7 RCC_GetFlagStatus
/**
* @brief Checks whether the specified RCC flag is set or not.
* @param RCC_FLAG: specifies the flag to check.
*
* For @b STM32_Connectivity_line_devices, this parameter can be one of the
* following values:
* @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
* @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
* @arg RCC_FLAG_PLLRDY: PLL clock ready
* @arg RCC_FLAG_PLL2RDY: PLL2 clock ready
* @arg RCC_FLAG_PLL3RDY: PLL3 clock ready
* @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
* @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
* @arg RCC_FLAG_PINRST: Pin reset
* @arg RCC_FLAG_PORRST: POR/PDR reset
* @arg RCC_FLAG_SFTRST: Software reset
* @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
* @arg RCC_FLAG_WWDGRST: Window Watchdog reset
* @arg RCC_FLAG_LPWRRST: Low Power reset
*
* For @b other_STM32_devices, this parameter can be one of the following values:
* @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready
* @arg RCC_FLAG_HSERDY: HSE oscillator clock ready
* @arg RCC_FLAG_PLLRDY: PLL clock ready
* @arg RCC_FLAG_LSERDY: LSE oscillator clock ready
* @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready
* @arg RCC_FLAG_PINRST: Pin reset
* @arg RCC_FLAG_PORRST: POR/PDR reset
* @arg RCC_FLAG_SFTRST: Software reset
* @arg RCC_FLAG_IWDGRST: Independent Watchdog reset
* @arg RCC_FLAG_WWDGRST: Window Watchdog reset
* @arg RCC_FLAG_LPWRRST: Low Power reset
*
* @retval The new state of RCC_FLAG (SET or RESET).
*/
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
功能:
检查指定的 RCC 标志位设置与否
参数:
RCC_FLAG:待检查的 RCC 标志位
返回值:
RCC_FLAG 的新状态(SET 或者 RESET)
03. 独立看门狗接线图
04. 独立看门狗程序示例1
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
int main(void)
{
//初始化
OLED_Init();
OLED_ShowString(1, 1, "IWDG TEST");
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)
{
OLED_ShowString(2, 1, "IWDGRST");
delay_ms(500);
OLED_ShowString(2, 1, " ");
delay_ms(100);
RCC_ClearFlag();
}
else
{
OLED_ShowString(3, 1, "RST");
delay_ms(500);
OLED_ShowString(3, 1, " ");
delay_ms(100);
}
//写使能
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
//设置预分频
IWDG_SetPrescaler(IWDG_Prescaler_16);
//设置重装载值 1000 = 1 / 40K * 16 * x x = 2500
IWDG_SetReload(2499);
//喂狗
IWDG_ReloadCounter();
//看门狗使能
IWDG_Enable();
while(1)
{
//喂狗
IWDG_ReloadCounter();
delay_ms(1800);
}
return 0;
}
05. 独立看门狗程序示例2
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "key.h"
int main(void)
{
//初始化
OLED_Init();
//按键初始化
key_init();
OLED_ShowString(1, 1, "IWDG TEST");
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET)
{
OLED_ShowString(2, 1, "IWDGRST");
delay_ms(500);
OLED_ShowString(2, 1, " ");
delay_ms(100);
RCC_ClearFlag();
}
else
{
OLED_ShowString(3, 1, "RST");
delay_ms(500);
OLED_ShowString(3, 1, " ");
delay_ms(100);
}
//写使能
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
//设置预分频
IWDG_SetPrescaler(IWDG_Prescaler_16);
//设置重装载值 1000 = 1 / 40K * 16 * x x = 2500
IWDG_SetReload(2499);
//喂狗
IWDG_ReloadCounter();
//看门狗使能
IWDG_Enable();
while(1)
{
key_scan();
//喂狗
IWDG_ReloadCounter();
OLED_ShowString(4, 1, "FEED");
delay_ms(200);
OLED_ShowString(4, 1, " ");
delay_ms(600);
}
return 0;
}
06. 窗口看门狗相关API
6.1 WWDG_DeInit
/**
* @brief Deinitializes the WWDG peripheral registers to their default reset values.
* @param None
* @retval None
*/
void WWDG_DeInit(void)
功能:
将外设 WWDG 寄存器重设为缺省值
参数:
无
返回值:
无
6.2 WWDG_SetPrescaler
/**
* @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)
功能:
设置 WWDG 预分频值值
参数:
WWDG_Prescaler:指定 WWDG 预分频
返回值:
无
6.3 WWDG_SetWindowValue
/**
* @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)
功能:
设置 WWDG 窗口值
参数:
WindowValue r:指定的窗口值。该参数取值必须在 0x40 与 0x7F 之间。
返回值:
无
6.4 WWDG_EnableIT
/**
* @brief Enables the WWDG Early Wakeup interrupt(EWI).
* @param None
* @retval None
*/
void WWDG_EnableIT(void)
功能:
使能 WWDG 早期唤醒中断(EWI)
参数:
无
返回值:
无
6.5 WWDG_SetCounter
/**
* @brief Sets the WWDG counter value.
* @param Counter: specifies the watchdog counter value.
* This parameter must be a number between 0x40 and 0x7F.
* @retval None
*/
void WWDG_SetCounter(uint8_t Counter)
功能:
设置 WWDG 计数器值
参数:
Counter:指定看门狗计数器值。该参数取值必须在 0x40 与 0x7F 之间。
返回值:
无
6.6 WWDG_Enable
/**
* @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.
* @retval None
*/
void WWDG_Enable(uint8_t Counter)
功能:
使能 WWDG 并装入计数器值
参数:
Counter:指定看门狗计数器值。该参数取值必须在 0x40 与 0x7F 之间。
返回值:
无
6.7 WWDG_GetFlagStatus
/**
* @brief Checks whether the Early Wakeup interrupt flag is set or not.
* @param None
* @retval The new state of the Early Wakeup interrupt flag (SET or RESET)
*/
FlagStatus WWDG_GetFlagStatus(void)
功能:
检查 WWDG 早期唤醒中断标志位被设置与否
参数:
无
返回值:
早期唤醒中断标志位的新状态(SET 或者 RESET)
6.8 WWDG_ClearFlag
/**
* @brief Clears Early Wakeup interrupt flag.
* @param None
* @retval None
*/
void WWDG_ClearFlag(void)
功能:
清除早期唤醒中断标志位
参数:
无
返回值:
无
07. 窗口看门狗接线图
08. 窗口看门狗程序示例
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "key.h"
int main(void)
{
//初始化
OLED_Init();
//按键初始化
key_init();
//开启WWDG时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
OLED_ShowString(1, 1, "WWDG TEST");
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)
{
OLED_ShowString(2, 1, "WWDGRST");
delay_ms(500);
OLED_ShowString(2, 1, " ");
delay_ms(100);
RCC_ClearFlag();
}
else
{
OLED_ShowString(3, 1, "RST");
delay_ms(500);
OLED_ShowString(3, 1, " ");
delay_ms(100);
}
//设置预分频
WWDG_SetPrescaler(WWDG_Prescaler_8);
//设置窗口值
WWDG_SetWindowValue(21 | 0x40);
//使能看门狗
WWDG_Enable(0x40 | 54);
while(1)
{
key_scan();
OLED_ShowString(4, 1, "FEED");
delay_ms(10);
OLED_ShowString(4, 1, " ");
delay_ms(10);
//喂狗
WWDG_SetCounter(0x40 | 54);
}
return 0;
}