cortex_m3_stm32嵌入式學習筆記(六):窗口看門狗實驗(WWDG)

ARM 202瀏覽

窗口看門狗( WWDG)通常被用來監測由外部干擾或不可預見的邏輯條件造成的應用程序背離正常的運行序列而產生的軟件故障

簡單來說,和IWDG的區別就是IWDG要靠手動去喂狗,而WWDG有內置中斷,所以可以利用設置中斷服務函數去喂狗

首先還是設置WWDG (記得往工程里面添加頭文件)大致設置步驟如下:

1)使能 WWDG 時鐘(系統內部時鐘)

2)設置窗口值和分頻數

3)開啟 WWDG 中斷并分組

4) 設置計數器初始值并使能看門狗

5) 編寫中斷服務函數

wwdg.c


#include "led.h" #include "wwdg.h" //保存 WWDG 計數器的設置值,默認為最大. u8 WWDG_CNT=0x7f; void WWDG_Init(u8 tr,u8 wr,u32 fprer) { 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); 	WWDG_SetPrescaler(fprer);////設置 IWDG 預分頻值         WWDG_SetWindowValue(wr);//設置窗口值 	WWDG_Enable(tr); //使能看門狗 , 設置 counter . 	WWDG_ClearFlag(); 	WWDG_NVIC_Init();//初始化窗口看門狗 NVIC         WWDG_EnableIT(); //開啟窗口看門狗中斷 } void WWDG_NVIC_Init(void) { 	NVIC_InitTypeDef NVIC_ist; 	NVIC_ist.NVIC_IRQChannel=WWDG_IRQn; 	NVIC_ist.NVIC_IRQChannelPreemptionPriority=2; 	NVIC_ist.NVIC_IRQChannelSubPriority=3; 	NVIC_ist.NVIC_IRQChannelCmd=ENABLE; 	NVIC_Init(&NVIC_ist); } void WWDG_IRQHandler(void) { 	WWDG_SetCounter(0x7f);//喂狗 	WWDG_ClearFlag();//清除提前喚醒標志 	LED1=!LED1;//檢測中斷函數是否工作了 } 

wwdg.h

#ifndef _WWDG_H #define _WWDG_H #include "sys.h" void WWDG_Init(u8 tr,u8 wr,u32 fprer); void WWDG_NVIC_Init(void); void WWDG_IRQHandler(void); #endif

其中有一個地方一開始寫錯了。。WWDG_Init()的第三個參數 寫成了u8 ..結果燈閃的超級快,后來找了一會才找到這錯了。。估計參數穿進去溢出了

主函數

#include "led.h" #include "sys.h" #include "delay.h" #include "wwdg.h" #include "usart.h" void init(void) { 	delay_init(); 	uart_init(9600); 	LED_Init(); 	NVIC_Configuration(); 	LED0=0; 	delay_ms(300); 	WWDG_Init(0x7f,0x5f,WWDG_Prescaler_8); } int main(void) { 	init(); 	while(1) 	{ 		LED0=1; 	} 	 }

主函數就是實現讓LED0先亮一下,然后WWDG就會工作(不讓程序復位),然后中斷函數就會工作,具體現象是LED1一直閃,一開始不明白中斷是如何觸發的,回頭翻了一下手冊,書上是這樣說的:窗口看門狗的第二個寄存器是配置寄存器( WWDG_CFR),該位中的 EWI 是提前喚醒中斷,也就是在快要產生復位的前一段時間( T[6:0]=0X40) 來提醒我們,需要進行喂狗了,否則將復位!因此,我們一般用該位來設置中斷,當窗口看門狗的計數器值減到 0X40 的時候,如果該位設置并開啟了中斷,則會產生中斷,我們可以在中斷里面向 WWDG_CR 重新寫入計數器的值,來達到喂狗的目的。

簡單來講(只是個人愚見)就是WWDG是一個遞減的計數器,從最大值遞減到0,到0的時候如果沒喂狗(就是重置計數器,比如說將它重置為最大值)就會復位,但中斷觸發是在中途進行的,就是當遞減到0x40的時候就會觸發中斷,這時候會轉到我們寫的中斷服務函數里面去,只要我們在中斷服務函數里面寫喂狗函數就可以一直喂狗了


七星彩走势图2元网官网