【STM32 标准库】看门狗

1.看门狗简介

    1.1 看门狗        

    stm32芯片内部有2个看门狗外设,分别为独立看门狗(IWDG)窗口看门狗(WWDG),用于检测并解决软件错误导致的故障。

    1.2 IWDG

    IWDG:12位递减计数器。如果计数器从某个值递减到0时,系统会产生一次复位。如果在计数器递减到0之前刷新了计数器(喂狗),就不会产生复位。

 1.3 WWDG

    WWDG:7位递减计数器。当计数器减到一个固定值0X40时还不喂狗,会产生一个MCU复位,称为窗口的下限。同时,用户可以设置一个上限值(窗口的上限),当计数器减到上限值之前时也会产生复位。只有在上窗口和下窗口之间时,才能刷新(喂狗)。

2.看门狗配置

    2.1 IWDG配置

    (1)添加头文件:stm32f10x_iwdg.c 和 stm32f10x_iwdg.h

    (2)开启寄存器访问(给 IWDG_KR 寄存器写入 0X5555)

    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

    (3)设置 IWDG 预分频系数和重装载值

void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);

void IWDG_SetReload(uint16_t Reload); Tout = (4*2^pre) / 40 * rlr     

(4)重载计数器值(喂狗)(给 IWDG_KR 寄存器写入 0XAAAA) 

    IWDG_ReloadCounter(); 

    (5)开启 IWDG(给 IWDG_KR 寄存器写入 0XCCCC) IWDG_Enable();

  2.2 WWDG配置

    (1)添加头文件:stm32f10x_wwdg.c 和 stm32f10x_wwdg.h

    (2)使能 WWDG 时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); 

    (3)设置 WWDG 窗口值、分频数 

    void WWDG_SetWindowValue(uint8_t WindowValue); 

    void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); 

    (4)开启 WWDG 中断并分组 

    WWDG_ClearFlag();

    WWDG_EnableIT(); 

    (5)设置计数器初始值并使能WWDG 

    void WWDG_Enable(uint8_t Counter); 

    void WWDG_SetCounter(uint8_t Counter);  //喂狗函数

    (6)编写 WWDG 中断服务函数

    WWDG_IRQHandler

3.硬件设计

4.软件设计

    4.1 功能描述

    4.1.1 IWDG功能描述

    4.2.1 WWDG功能描述

    本章所要实现的功能是:系统开启时 DS0 指示灯点亮 500ms 时间,然后熄灭。 DS1 指示灯不断闪烁表示正在喂狗。如果喂狗超时将重启系统,DS0 指示灯点亮 500ms,然后熄灭,继续喂狗。

    4.2 软件实现

    4.2.1 IWDG软件实现

    (1)初始化IWDG

#include "IWDG.h"
// -----------------------------1.IWDG初始化-------------------------------------
/* ---------------------------------函数声明-------------------------------------
*函数名称:void IWDG_Iint(u8 pre, u16 rlr)
*输入参数:u8 pre, u16 rlr
*返回参数:无
*功    能:IWDG初始化
*作    者:lph
*日    期:2024/03/28
------------------------------------------------------------------------------ */
void IWDG_Iint(u8 pre, u16 rlr)
{
    //(1)开启寄存器访问(给 IWDG_KR 寄存器写入 0X5555)
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
    //(2)设置 IWDG 预分频系数和重装载值:Tout = (4*2^pre) / 40 * rlr
    IWDG_SetPrescaler(pre);
    IWDG_SetReload(rlr);
    //(3)重载计数器值(喂狗)(给 IWDG_KR 寄存器写入 0XAAAA)
    IWDG_ReloadCounter();
    //(4)开启 IWDG(给 IWDG_KR 寄存器写入 0XCCCC)
    IWDG_Enable();
}
/* ---------------------------------函数声明-------------------------------------
*函数名称:void IWDG_FeedDog(void)
*输入参数:无
*返回参数:无
*功    能:IWDG喂狗
*作    者:lph
*日    期:2024/03/28
------------------------------------------------------------------------------ */
void IWDG_FeedDog(void)
{
    IWDG_ReloadCounter();
}

  (2)主函数

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "system.h"
#include "LED.h"
#include "KEY.h"
#include "SysTick.h"
#include "USART.h"
#include "IWDG.h"
/* 主函数main() --------------------------------------------------------------*/
int main()
{   
    // 自定义变量
    u8 i=0;
    // 初始化
    SysTick_Iint(72);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
    LED_Init();
    KEY_Iint();
    USART1_Iint(115200);
    IWDG_Iint(4, 800);  //1280ms
    
    LED1 = 1;
    printf("系统复位\r\n");
    
    while(1)
    {
        if(KEY_Scan(0)==KEY_UP_PRESS)
        {
            IWDG_FeedDog();
            LED0 = 0;
            printf("喂狗\r\n");
        }
        
        i++;
        if(i%50==0)
        {
            LED1 = !LED1;
        }
        delay_ms(10);
    }
}

  4.2.2 WWDG软件实现

    (1)初始化WWDG

#include "WWDG.h"
void WWDG_Iint(void)
{
    //(2)使能 WWDG 时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
    
    //(3)设置 WWDG 窗口值、分频数
    WWDG_SetWindowValue(0x5F);   //用户设置上窗口值
    WWDG_SetPrescaler(WWDG_Prescaler_8);
    
    //(4)开启 WWDG 中断并分组
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    //(5)设置计数器初始值并使能WWDG
    WWDG_Enable(0x7f);
    WWDG_ClearFlag();
    WWDG_EnableIT();
}
void WWDG_IRQHandler(void)
{
    WWDG_SetCounter(0x7f);
    WWDG_ClearFlag();
    LED1 = !LED1;
}

    (2)主函数

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "system.h"
#include "LED.h"
#include "SysTick.h"
#include "USART.h"
#include "WWDG.h"
/* 主函数main() --------------------------------------------------------------*/
int main()
{   
    // 自定义变量
    // 初始化
    SysTick_Iint(72);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
    USART1_Iint(115200);
    
    LED0 = 0;
    delay_ms(500);
    LED0 = 1;
    WWDG_Iint();
    while(1)
    {
        
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值