赞
踩
窗口看门狗简介
窗口看门狗( 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一直翻转。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。