首页 > 技术文章 > STM32之独立看门狗

nwjlq 2020-06-03 21:13 原文

简介:

stm32f0x内置两个看门狗(独立看门狗 窗口看门狗)。用来检测或解决由软件引发的错误故障。对于独立看门狗,其本质为一个12位的递减计数器。当减到0是,会产生复位信号。我们可以在数值减到0之前给递减计数器重新赋值(这一行为称为喂狗)来防止产生复位信号。

功能框图:

1.独立看门狗时钟来源LSI(内部低速时钟),时钟频率为40KHz.

2.LSI时钟通过配置IWDG_PR寄存器进行分频,得到计数器时钟CK_CNT.

 

从参考手册可以看出可以进行4*2^(PR)分频,如001的分频因子为4*2^(1)=8

由于这个寄存器具有写保护设置。可以通过对键寄存器进行配置来取消写保护设置

从参考手册可以知道,对键寄存器写0x5555表示取消IWDG_PR 和IWDG_RLL寄存器的写保护设置

                                                       写0xAAAA表示喂狗,即将重装载寄存器中的值装载到计数器中

                                                      写0xCCCC表示启动看门狗

3.12位的递减计数器,最大值为0xfff,每隔1/CK_CNT(s)的时间,计数器的值减1,当减到0时,产生系统复位信号。

  如:设置分频系数为64,则CN_CNT为LSI/分频系数=625Hz 计数器每减一次的时间为1/625 s,如果设置计数器初值/重装载值为625则每隔1s产生复位信号

 4.当递减计数器的值减到0或喂狗时,从重装载寄存器中将数值装载到计数器中

5.见上面的键寄存器

6.状态寄存器

RVU:为1表示正在重装载,装载结束,硬件清0

PVU:为1表示预分频值正在更新,跟新结束,硬件清0

 

对独立看门狗操作的函数:

实验:

   如果由于独立看门狗导致复位,LED1会闪烁,否则LED1一直亮

原理图:

独立看门狗头文件即源文件:

#ifndef _IWDG_H
#define _IWDG_H
#include "stm32f10x.h"
void IWDG_Config(void);
void free_dog(void);
#endif
#include "iwdg.h"

void IWDG_Config(void)
{
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//取消写保护设置
    IWDG_SetPrescaler(IWDG_Prescaler_64);//设置分频因子
    IWDG_SetReload(625);//设置重装载值
    IWDG_Enable();//开启看门狗
}

void free_dog(void)
{
    IWDG_ReloadCounter();//喂狗
}

设置分频系数为64,重装载值为625,则每隔1s产生复位

main文件

#include "stm32f10x.h"
#include "iwdg.h"
void LED_KEY_GPIO_Config(void);
int main(void)
{
    LED_KEY_GPIO_Config();
    IWDG_Config();
    for(uint32_t i=0;i<5000000;i++);//在此延时是为了更好观察效果
    while(1)
    {
        GPIO_ResetBits(GPIOC,GPIO_Pin_0);
        //上键按下 喂狗
        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==SET)
        {
            free_dog();
        }
    }
}

void LED_KEY_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    //led1初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOC,&GPIO_InitStruct);
    GPIO_SetBits(GPIOC,GPIO_Pin_0);//默认熄灭
    //上键初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
}

推荐阅读