独立看门狗IWDG详细解析
为什么要有看门狗?
看门狗的定时原理
寄存器功能简介
看门狗定时器计数原理
看门狗相关寄存器
KR寄存器
PR寄存器
RLR寄存器
SR寄存器
看门狗相关基础知识
什么是“溢出时间”?
溢出时间指的是“从重装载值递减至0的时间”,当距离上次使能键寄存器的时间超过溢出时间,那么看门狗会自动复位,重投开始执行程序。例如:当我们设定溢出时间为1s,但是我们操作键寄存器距离上次使能键寄存器的时间已经是1.2s了,这说明程序已经Reset复位,从头开始执行(从main函数的头部开始执行)。
预分频系数有什么用?
“溢出时间”如何计算?
不同预分频系数,不同重装载值对应的溢出时间
最短超时时间与最长超时时间
最短超时时间
| 当重装载值是1且预分频系数为1时,溢出时间为(1/40KHz)s
|
最长超时时间
| 当重装载值是0x0FFF且预分频系数是256时,溢出时间是(1/40KHz*256*0xFFF)s
|
IWDG独立看门狗操作库函数
IWDG独立看门狗操作步骤
步骤说明
| 对应库函数说明
|
取消寄存器写保护
| IWDG_WriteAccessCmd()
|
设置独立看门狗的预分频系数,确定时钟
| IWDG_SetPrescaler()
|
设置看门狗重装载值,确定溢出时间
| IWDG_SetReload()
|
应用程序喂狗
| IWDG_ReloadCounter()
|
使能看门狗
| IWDG_Enable()
|
函数示例
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的属性
// 切记:引脚在输入状态不可以给予引脚初始电平
}
运行结果
当我们在复位之前按下KEY0时,LED0不会闪烁,LED0会保持亮的状态。
独立看门狗IWDG详细解析
为什么要有看门狗?
看门狗的定时原理
寄存器功能简介
看门狗定时器计数原理
看门狗相关寄存器
KR寄存器
PR寄存器
RLR寄存器
SR寄存器
看门狗相关基础知识
什么是“溢出时间”?
溢出时间指的是“从重装载值递减至0的时间”,当距离上次使能键寄存器的时间超过溢出时间,那么看门狗会自动复位,重投开始执行程序。例如:当我们设定溢出时间为1s,但是我们操作键寄存器距离上次使能键寄存器的时间已经是1.2s了,这说明程序已经Reset复位,从头开始执行(从main函数的头部开始执行)。
预分频系数有什么用?
“溢出时间”如何计算?
不同预分频系数,不同重装载值对应的溢出时间
最短超时时间与最长超时时间
最短超时时间
| 当重装载值是1且预分频系数为1时,溢出时间为(1/40KHz)s
|
最长超时时间
| 当重装载值是0x0FFF且预分频系数是256时,溢出时间是(1/40KHz*256*0xFFF)s
|
IWDG独立看门狗操作库函数
IWDG独立看门狗操作步骤
步骤说明
| 对应库函数说明
|
取消寄存器写保护
| IWDG_WriteAccessCmd()
|
设置独立看门狗的预分频系数,确定时钟
| IWDG_SetPrescaler()
|
设置看门狗重装载值,确定溢出时间
| IWDG_SetReload()
|
应用程序喂狗
| IWDG_ReloadCounter()
|
使能看门狗
| IWDG_Enable()
|
函数示例
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的属性
// 切记:引脚在输入状态不可以给予引脚初始电平
}
运行结果
当我们在复位之前按下KEY0时,LED0不会闪烁,LED0会保持亮的状态。
举报