简介:
跟独立看门狗一样,也是用来检测软件可能出现的错误,不一样的是,当独立看门狗计数器的值减到0时会产生复位,在减到0之前喂狗防止复位。
窗口看门狗:在某一值到0x40之间喂狗才不会产生复位,其他情况均会产生复位信号,这个某一个值称之为窗口上限。
计数器数值由看门狗控制寄存器决定
可以看出计数器占7位,最大值为0x7f
功能框图:
1.PCLK1默认为36MHz
2.PCLK1经过分频器分频生成CNT_CK给计数器提供时钟
从图中可以看出CNT_CK=PCLK1/4096/(2^WDGTB)
3.计数器,见最上面第1 2张图,当计数器最高位T6由1变为0时,产生复位
4.设置窗口上限值,见配置寄存器,窗口上限值不得大于计数器最大值,不得小于窗口下限值
超时时间计算:超时时间指计数器值减到窗口下限下一个数值即0x3f所花时间
最短超时时间在计数器的值为0x40的时候,最长超时时间在计数器值为0x7f的时候
当WDGTB为0时,CNT_CK=36M/4096/1=8789.0625Hz 计数器减一次所花时间为 1/8789.0625(s) 最短超时时间=(0x40-0x3f)*/8789.0625 约等于113us
最长超时时间=(0x7f-0x3f)/8789.0625 约等于7.28ms
相关函数:
上面中的中断函数使能是当计数器从0x40减到0x3f时产生的,这个中断称为死前中断。
实验:
设置计数器值和窗口上限值都为0x7f
配置死前中断,在中断中喂狗,并且LED2反转
main函数中,LED1一直点亮
原理图:
看门狗头文件和源文件:
#ifndef _WWDG_H #define _WWDG_H #include "stm32f10x.h" void WWDG_Config(void); #endif
#include "wwdg.h" static void LED1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStruct); GPIO_SetBits(GPIOC,GPIO_Pin_1);//默认熄灭 } //中断优先级配置 static void WWDG_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStruct.NVIC_IRQChannel=WWDG_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct); } void WWDG_Config(void) { WWDG_NVIC_Config(); LED1_GPIO_Config(); RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//开启看门狗时钟 WWDG_SetPrescaler(WWDG_Prescaler_8);//设置分频系数 WWDG_SetWindowValue(0x7f);//设置窗口上限值 WWDG_SetCounter(0x7f);//设置计数器值 WWDG_EnableIT();//使能中断 WWDG_Enable(0x7f);//开启看门狗 } void WWDG_IRQHandler(void) { WWDG_ClearFlag(); WWDG_SetCounter(0x7f);//设置计数器值 //LED2反转 if(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_1)==SET) GPIO_ResetBits(GPIOC,GPIO_Pin_1); else GPIO_SetBits(GPIOC,GPIO_Pin_1);//默认熄灭 }
mian文件:
#include "stm32f10x.h" #include "wwdg.h" static void LED0_GPIO_Config(void); int main(void) { LED0_GPIO_Config(); WWDG_Config(); while(1); } static void LED0_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; 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_ResetBits(GPIOC,GPIO_Pin_0);//默认点亮 }
原文:https://www.cnblogs.com/nwjlq/p/13046724.html