窗口看门狗(WWDG)
窗口看门狗WWDG其实和独立看门狗类似,它是一个7位递减计数器不断的往下递减计数,当减到一个固定值 0X40 时还不喂狗的话,产生一个MCU复位,这个值叫窗口的下限,是固定的值,不能改变。这个和独立看门狗是类似的,不同的是窗口看门狗的计数器的值在减到某一个数之前喂狗的话也会产生复位,这个值叫窗口的上限,上限值由用户独立设置。窗口看门狗计数器的值必须在上窗口和下窗口之间才可以刷新(喂狗),这也是窗口看门狗中“窗口”两个字的含义。
窗口时钟来源于RCC的PCLK1时钟,位于APB1总线上,42mHz。
(1)标号1:WWDG时钟
(2)标号2:WDG预分频器器
分频后的计数器时钟为:CK_CNT= PCLK1/4096/(2^WDGTB),除以4096是中文参考手册内公式规定。
(3)标号3:计数器
窗口看门狗的超时时间计算公式如下:Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /PCLK1;
Twwdg为窗口看门狗的超时时间,单位为ms。
PCLK1为APB1的时钟频率,最大42MHz。
WDGTB为窗口看门狗的预分频系数。
T[5:0]为窗口看门狗的计数器低6位。
(4)标号4:看门狗配置寄存器
设置上窗口值;
(5)标号5:系统复位信号
WWDG配置步骤:
(1)使能WWDG时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
(2)设置WWDG窗口值和分频数
void WWDG_SetWindowValue(uint8_t WindowValue);
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
分频系数可以为WWDG_Prescaler_1、WWDG_Prescaler_2、WWDG_Prescaler_4、W
WDG_Prescaler_8。
(3)开启WWDG中断并分组
NVIC_Init();
WWDG_EnableIT();
(4)设置计数器初始值并使能WWDG
void WWDG_Enable(uint8_t Counter);
//void WWDG_SetCounter(uint8_t Counter);
(5)编写WWDG中断服务函数
WWDG_IRQHandler
WWDG_ClearFlag();
窗口看门狗源文件:
#include "wwdg.h"
#include "led.h"
void wwdg_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
WWDG_SetWindowValue(0x5f); //上窗口值不能超过0x7f 下窗口值默认0x40
WWDG_SetPrescaler(WWDG_Prescaler_8); //分频系数
//配置NVIC
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//窗口看门狗中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
WWDG_Enable(0x7f); //设置喂狗计数器初值(7位)
WWDG_ClearFlag(); //清除中断标志位
WWDG_EnableIT(); //开启中断
}
//喂狗中断服务函数
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(0x7f); //重新赋值
WWDG_ClearFlag();
led2 = !led2; //led2闪烁表示喂狗
}
主函数:
#include "usart.h"
#include "iwdg.h"
#include "wwdg.h"
int main()
{
SysTick_Init(168);
LED_Init();
KEY_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
//TIM14_CH1_PWM_Init(400-1,84-1);//84MHz分频为84即1MHz为1us,计数500次为500us,频率为2KHz
led1 = 0; //程序最开始led1亮然后进入while循环led1不亮,由于窗口看门狗一直在喂狗所以程序一直没有复位。
myDelay_ms(500);
wwdg_Init();
while(1)
{
led1 = 1;
}
}