独立看门狗

一,看门狗简介

由于单片机会受到来自外界电磁场的干扰,造成程序跑飞使系统陷入死循环,造成不可预知的后果
于是有了用于检测单片机程序运行状态的模块或芯片,叫做”看门狗”(watchdog)

看门狗作用:检测系统,当系统跑飞时复位系统,重新执行程序


二,STM32看门狗

STM32有两个看门狗:独立看门狗和窗口看门狗

独立看门狗:

 驱动:由LSI驱动,即使主时钟发生故障它仍有效

 适用场景:
      作为主程序之外能够完全独立工作
      对时间精度要求较低

窗口看门狗:

 驱动:由APB1时钟分频后得到时钟驱动

 适用场景:
      在精确计时窗口起作用的程序

三,独立看门狗原理

启动:键值寄存器IWDG_KR写入0xCCCC开始启用独立看门狗
过程:计时器从重装载值(由寄存器IWDG_RLR配置,默认0xFFF)开始递减,当递减到0x000时产生复位信号IWDG_RESET
喂狗:键值寄存器IWDG_KR写入0xAAAA,重装载寄存器IWDG_RLR的值会重新加载到递减计数器,避免看门狗复位
复位:如果程序异常跑飞,不能完成喂狗,系统复位

独立看门狗_第1张图片

如图:
    独立看门狗时钟LSI通过预分频(IWDG_PR)
    向减值寄存器IWDG_KR写入0xCCCC,开启独立看门狗,此时重装载值写入递减计数器
    在任何时间向IWDG_KR写入0xAAAA完成喂狗,重装载寄存器IWDG_RLR的值会重新加载到递减计数器,避免看门狗复位
    如果在0xFFF递减到0x000前未完成喂狗,系统复位

四,独立看门狗相关寄存器

键值寄存器IWDG_KR: 0~15位有效

独立看门狗_第2张图片

写入0x5555取消IWDG_PR和IWDG_RLR写保护
写入0xCCCC开启独立看门狗
写入0xAAAA喂狗

预分频寄存器IWDG_PR:0~2位有效。具有写保护功能,要操作先取消写保护

独立看门狗_第3张图片

重装载寄存器IWDG_RLR:0~11位有效。具有写保护功能,要操作先取消写保护。

独立看门狗_第4张图片

0-11位[11:0]有效,[12:31]位保留 默认值,最大值为0xFFF
当IWDG_KR写入0xAAAA是,重装载值会被传送到计数器中
IWDG_SR寄存器RVU位为0时才能对IWDG_RLR寄存器进行修改

状态寄存器IWDG_SR:0~1位有效

独立看门狗_第5张图片


五,独立看门狗超时时间

独立看门狗_第6张图片

看门狗时钟源 : 由LSI经过IWDG_PR分频提供
     LSI时钟频率=40MHz
     IWDG_PR预分频系数 P = 4 * 2^prer
     所以看门狗时钟频率 = 40/P

IWDG_RLR计数器重装载值,每经过一个看门狗时钟周期-1
看门狗时钟周期 = P/40

看门狗移除时间:
     Tout = ((4 * 2^prer) * RLR) / 40

最短时间 : 一个看门狗时钟周期  即IWDG_RLR=0x001
最长时间 : IWDG_RLR寄存器最大值(0xFFF) * 看门狗时钟周期

六,独立看门狗相关库函数


void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); // 取消写保护:0x5555使能
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);    // 设置预分频系数:写PR
void IWDG_SetReload(uint16_t Reload);          // 设置重装载值:写RLR
void IWDG_ReloadCounter(void);              // 喂狗:写0xAAAA到KR
void IWDG_Enable(void);                  // 使能看门狗写0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);  // 状态:重装载/预分频 更新

七,独立看门狗操作步骤

//取消寄存器写保护:
    IWDG_WriteAccessCmd();
//设置独立看门狗的预分频系数,确定时钟:
    IWDG_SetPrescaler();
//设置看门狗重装载值,确定溢出时间:
    IWDG_SetReload();
//使能看门狗
    IWDG_Enable();
//应用程序喂狗:
    IWDG_ReloadCounter();
//溢出时间计算:
    Tout=((4×2^prer)×rlr) /40

八,独立看门狗代码:

功能:
        独立看门狗设置1秒溢出,按下WK_UP按键喂狗
        如果不喂狗可以看到每1秒程序重启一次
        现象LED0闪烁,因为每次启动程序有500毫秒延时
        若连续快速按下WK_UP,使看门狗不进入溢出,LED0常亮

HAEDWARE/IWDG下新建Iwdg.h头文件

#ifndef __WDG_H
#define __WDG_H
#include “sys.h” //因为使用了u8 u16
/**
 * 看门狗初始化
 *     prer     预分频系数
 *     rlr      重装载值
 */
void IWDG_Init(u8 prer,u16 rlr);
void IWDG_Feed(void);  // 喂狗
#endif

头文件添加到项目配置
独立看门狗_第7张图片

HAEDWARE/IWDG下新建Iwdg.c实现函数

在stm32f10x_iwdg.h中找到:

/** @defgroup IWDG_Exported_Functions
  * @{
  */
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);     // 取消写保护
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);          // 设置预分频系数
void IWDG_SetReload(uint16_t Reload);                    // 设置重装载值
void IWDG_ReloadCounter(void);                           // 喂狗
void IWDG_Enable(void);                                  // 使能独立看门狗
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);       // 获取状态
#include "wdg.h"

//看门狗初始化
void IWDG_Init(u8 prer,u16 rlr)
{
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);  // 取消IWDG_PR WDG_RLR写保护

    IWDG_SetPrescaler(prer);  // 设置预分频系数

    IWDG_SetReload(rlr);      // 设置重装载值

    IWDG_ReloadCounter();     // 喂狗-使第一次从重装载值开始计数,默认首次0xFFF

    IWDG_Enable();            // 使能看门狗
}

// 喂狗
void IWDG_Feed(void)
{
     IWDG_ReloadCounter();    // reload
}

USER/main.编写主函数

#include "led.h"         // LED
#include "delay.h"       // 延时函数
#include "key.h"         // 按键
#include "sys.h"
#include "usart.h"
#include "wdg.h"         // 独立看门狗

 int main(void)
 {
    delay_init();        // 延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // NVIC中断优先级分组
    uart_init(115200);   // 设置USART波特率115200
    LED_Init();          // LED端口初始化 - 默认LED0熄灭
    KEY_Init();          // 按键端口初始化

    delay_ms(500);       // 延时500ms - 复位时LED闪烁
    IWDG_Init(4, 625);   // 独立看门狗初始化-设置溢出时间1S-预分频系数4,重装载值625
    LED0=0;              // LED0点亮
    while(1)
    {
        if(KEY_Scan(0)==WKUP_PRES) // 按下按键WK_UP
        {
            IWDG_Feed(); // 喂狗
        }
        delay_ms(10);
    };
}

以上代码实现:
    独立看门狗设置1秒溢出,按下WK_UP按键喂狗
    如果不喂狗可以看到每1秒程序重启一次
    现象LED0闪烁,因为每次启动程序有500毫秒延时
    若连续快速按下WK_UP,使看门狗不进入溢出,LED0常亮

你可能感兴趣的:(STM32,STM32学习笔记)