窗口看门狗

窗口看门狗简介
窗口看门狗( WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位 ( WWDG->CR 的第六位)变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。

这里写图片描述
图 1 窗口看门狗工作示意图
T[6:0]就是 WWDG_CR 的低七位, W[6:0]即是 WWDG->CFR 的低七位。T[6:0]
就是窗口看门狗的计数器。

注意
1、W[6:0]则是窗口看门狗的上窗口,由用户自己设定,下窗口值是固定的( 0X40)。
2、当窗口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。

窗口看门狗的超时公式如下:

Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;

其中:
Twwdg: WWDG 超时时间(单位为 ms)
Fpclk1: APB1 的时钟频率(单位为 Khz)
WDGTB: WWDG 的预分频系数
T[5:0]:窗口看门狗的计数器低 6 位

代码:
main.c


#include "led.h"
#include "key.h"
#include "beep.h"
#include "delay.h"
#include "wwdg.h"
#include "usart.h"

int main()
{

    delay_init();

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组;

    uart_init(115200);

    LED_Init();

    KEY_Init();

    LED0 = 0;

    delay_ms(200);

    WWDG_Init(0x7F, 0x5F, WWDG_Prescaler_8); 

    while(1)
    {
        printf("OK\r\n");
        LED0 = 1;
    }

}

wwdg.h

#ifndef __WGD_H
#define __WGD_H

#include "sys.h"
#include "led.h"

void WWDG_Init(u8 tr,u8 wr,u32 fprer);
void WWDG_Set_Counter(u8 cnt);
void WWDG_NVIC_Init(void);

#endif

wwdg.c

#include "wwdg.h"


u8 WWDG_CNT = 0x7f;  // 用来保存WWDG_CR计数器的值;

void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);

    WWDG_CNT = tr&WWDG_CNT;         // 初始化WWDG_CNT;
    WWDG_SetPrescaler(fprer);       // 设置IWDG预分频值;
    WWDG_SetWindowValue(wr);        // 设置窗口值;
    WWDG_Enable(WWDG_CNT);          // 使能看门狗,设置counter;
    WWDG_ClearFlag();               // 清除提前唤醒中断标志位;
    WWDG_NVIC_Init();               // 初始化窗口看门狗;
    WWDG_EnableIT();                // 开启窗口看门狗中断;
}

// 重设置WWDG计数器的值;
void WWDG_Set_Counter(u8 cnt)
{
    WWDG_Enable(cnt);
}

// 初始化中断
void WWDG_NVIC_Init(void)
{
    NVIC_InitTypeDef NVIC_InitStructrue;
    NVIC_InitStructrue.NVIC_IRQChannel = WWDG_IRQn;
    NVIC_InitStructrue.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructrue.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructrue.NVIC_IRQChannelSubPriority = 3;
    NVIC_Init(&NVIC_InitStructrue);
}

// 中断服务函数;
void WWDG_IRQHandler(void )
{
    WWDG_SetCounter(WWDG_CNT);  // 重新装载计数器值;
    WWDG_ClearFlag();           // 清除中断标志位;
    LED1=!LED1;                 // LED状态翻转;
}

实验结果
LED0 亮 200ms后,LED1一直翻转。
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值