独立看门狗IWDG详细解析

目录

独立看门狗IWDG详细解析

为什么要有看门狗?

看门狗的定时原理

寄存器功能简介

看门狗定时器计数原理

看门狗相关寄存器

KR寄存器

PR寄存器

RLR寄存器

SR寄存器

看门狗相关基础知识

什么是“溢出时间”?

预分频系数有什么用?

“溢出时间”如何计算?

不同预分频系数,不同重装载值对应的溢出时间

最短超时时间与最长超时时间

IWDG独立看门狗操作库函数

IWDG独立看门狗操作步骤

函数示例

Main.c

Led.c

Led.h

Iwdg.c

Iwdg.h

Key.h

Key.c

运行结果


独立看门狗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会保持亮的状态。

 

猜你喜欢

转载自blog.csdn.net/weixin_45590473/article/details/108011731