簡介:
跟獨立看門狗一樣,也是用來檢測軟件可能出現的錯誤,不一樣的是,當獨立看門狗計數器的值減到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);//默認點亮 }