table of Contents
Detailed analysis of independent watchdog IWDG
Why should there be a watchdog?
The timing principle of the watchdog
Introduction to Register Functions
Watchdog timer counting principle
How is "overflow time" calculated?
Different prescaler coefficients and overflow time corresponding to different reload values
Minimum timeout period and maximum timeout period
IWDG independent watchdog operation library function
IWDG independent watchdog operation steps
Detailed analysis of independent watchdog IWDG
Why should there be a watchdog?
The timing principle of the watchdog
Introduction to Register Functions
Watchdog timer counting principle
Watchdog related registers
KR register
PR register
RLR register
SR register
Basic knowledge of watchdog
What is "overflow time"?
The overflow time refers to the "time to decrement from the reload value to 0". When the time from the last enable of the key register exceeds the overflow time, the watchdog will automatically reset, and the program will start to execute after reloading. For example: when we set the overflow time to 1s, but the time we have operated the key register from the last enable key register is 1.2s, this means that the program has been reset and executed from the beginning (executed from the head of the main function) ).
What is the use of prescaler?
How is "overflow time" calculated?
Different prescaler coefficients and overflow time corresponding to different reload values
Minimum timeout period and maximum timeout period
Minimum timeout |
When the reload value is 1 and the prescaler coefficient is 1, the overflow time is (1/40KHz)s |
Longest timeout |
When the reload value is 0x0FFF and the prescaler coefficient is 256, the overflow time is (1/40KHz*256*0xFFF)s |
IWDG independent watchdog operation library function
IWDG independent watchdog operation steps
Step description |
Corresponding library function description |
Cancel register write protection |
IWDG_WriteAccessCmd() |
Set the prescaler coefficient of the independent watchdog to determine the clock |
IWDG_SetPrescaler() |
Set watchdog reload value and determine overflow time |
IWDG_SetReload() |
App feeding the dog |
IWDG_ReloadCounter() |
Enable watchdog |
IWDG_Enable() |
Function example
Main.c
#include "iwdg.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "stm32f10x.h"
int main()
{
delay_init(); // 使能定时器初始化delay函数
delay_ms(500);
LED_InitConfig();
IWDG_InitConfig(625, IWDG_Prescaler_16); // 溢出时间为1s
KEY_InitConfig();
LED0 = 0;
while(1)
{
if(KEY0 == 0)
{
delay_ms(10);
if(KEY0 == 0)
{
IWDG_ReloadCounter(); // 配置KR寄存器将重装载值加载进递减计数器中
}
}
}
}
Led.c
#include "led.h"
#include "stm32f10x.h"
void LED_InitConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能外设时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化IO口属性
GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 初始化IO口状态
}
Led.h.
#ifndef _LED_H
#define _LED_H
#include "sys.h"
void LED_InitConfig();
#define LED0 PBout(5)
#endif
Iwdg.c
#include "iwdg.h"
#include "stm32f10x.h"
void IWDG_InitConfig(u16 RLR,u16 PR)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 先对KR寄存器写入0x5555来允许修改PR寄存器与RLR寄存器的值
IWDG_SetPrescaler(PR); // 给预分频寄存器设置预分频系数
IWDG_SetReload(RLR); // 在重装载寄存器中设置重装载值
IWDG_ReloadCounter(); // 对KR寄存器吸入0xAAAA来将重装载值装入递减计数器中替换默认值0x0FFF
IWDG_Enable(); // 对KR寄存器写入0xCCCC来配置完IWDG所有属性后使能IWDG独立看门狗
}
Iwdg.h
#ifndef _IWDG_H
#define _IWDG_H
#include "sys.h"
void IWDG_InitConfig(u16 RLR,u16 PR);
#endif
Key.h
#ifndef _KEY_H
#define _KEY_H
#include "stm32f10x.h"
void KEY_InitConfig();
#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)
#endif
Key.c
#include "key.h"
#include "stm32f10x.h"
void KEY_InitConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); // 使能外设时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure); // 配置KEY0的属性
// 切记:引脚在输入状态不可以给予引脚初始电平
}
operation result
When we press KEY0 before resetting, LED0 will not blink, and LED0 will remain on.