STM32之獨立看門狗(IWDG)和窗體看門狗(WWDG)
這個游戲以極高的自由度、出色的游戲質量與豐富的游戲內容被業界公認為開啟次世代游戲的大門之作,該游戲被IGN評為年度最佳射擊游戲(下載地址:http://down.ali213.net/pcgame/WatchDogs.html 有機會一定玩玩。)
二 開門見山:
下面言歸正傳,在工作中用的STM32需要使用看門狗技術:
看門狗通俗解釋:
單片機系統在外界的干擾下會出現程序跑飛的現象導致出現死循環,看門狗電路就是為了避免這種情況的發生。看門狗的作用就是在一定時間內(通過定時計數器實現)沒有接收喂狗信號(表示 MCU 已經掛了),便實現處理器的自動復位重啟(發送復位信號)。
三 廬山面目:
STM32芯片一共有兩個看門狗,一個是獨立看門狗(IWDG),另一個是窗體看門狗(WWDG)
①先來講講獨立看門狗:
STM32 的獨立看門狗由內部專門的 40Khz 低速時鐘驅動,即使主時鐘發生故障,它也仍然
有效。這里需要注意獨立看門狗的時鐘是一個內部 RC 時鐘,所以并不是準確的 40Khz,而是
在 30~60Khz 之間的一個可變化的時鐘,只是我們在估算的時候,以 40Khz 的頻率來計算,看
門狗對時間的要求不是很精確,所以,時鐘有些偏差,都是可以接受的。
獨立看門狗的配置工作代碼:
1 void IWDG_Init(u8 prer,u16 rlr)2 {3 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //①使能對寄存器 I 寫操作4 IWDG_SetPrescaler(prer); //②設置 IWDG 預分頻值:設置 IWDG 預分頻值5 IWDG_SetReload(rlr); //②設置 IWDG 重裝載值6 IWDG_ReloadCounter(); //③按照 IWDG 重裝載寄存器的值重裝載 IWDG 計數器7 IWDG_Enable(); //④使能 IWDG8 }9 //喂獨立看門狗10 void IWDG_Feed(void)11 {12 IWDG_ReloadCounter();//reload13 }
主邏輯區代碼:
1 delay_init();//延時函數初始化2 NVIC_Configuration(); //設置 NVIC 中斷分組 2:2 位搶占優先級,2 位響應優先級3 KEY_Init(); //按鍵初始化4 IWDG_Init(4,625); //與分頻數為 64,重載值為 625,溢出時間為 1s5 while(1)6 {7 if(KEY_Scan(0)==KEY_UP)8 {9 IWDG_Feed(); //如果 按鍵按下,則喂狗10 }11 delay_ms(10);12 }
程序的功能就是通過按鍵打開看門狗,當看門狗被觸發之后執行相應的操作。
②再來看看窗體看門狗
窗口看門狗(WWDG)通常被用來監測由外部干擾或不可預見的邏輯條件造成的應用程序
背離正常的運行序列而產生的軟件故障。除非遞減計數器的值在 T6 位(WWDG->CR 的第六位)
變成 0 前被刷新,看門狗電路在達到預置的時間周期時,會產生一個 MCU 復位。在遞減計數
器達到窗口配置寄存器(WWDG->CFR)數值之前,如果 7 位的遞減計數器數值(在控制寄存器中)
被刷新, 那么也將產生一個 MCU 復位。這表明遞減計數器需要在一個有限的時間窗口中被刷
新。
看門狗時間計算公式:
窗口看門狗的超時公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;
其中:
Twwdg:WWDG 超時時間(單位為 ms)
Fpclk1:APB1 的時鐘頻率(單位為 Khz)
WDGTB:WWDG 的預分頻系數
T[5:0]:窗口看門狗的計數器低 6 位
1 void WWDG_Init(u8 tr,u8 wr,u32 fprer)2 {3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 時鐘使能4 WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.5 WWDG_SetPrescaler(fprer); //設置 IWDG 預分頻值6 WWDG_SetWindowValue(wr); //設置窗口值7 WWDG_Enable(WWDG_CNT);8 //使能看門狗,設置 counter9 WWDG_ClearFlag(); //清除提前喚醒中斷標志位10 WWDG_NVIC_Init(); //初始化窗口看門狗 NVIC11 WWDG_EnableIT(); //開啟窗口看門狗中斷12 }13 //重設置 WWDG 計數器的值14 void WWDG_Set_Counter(u8 cnt)15 {16 WWDG_Enable(cnt); //使能看門狗,設置 counter .17 }18 //窗口看門狗中斷服務程序19 void WWDG_NVIC_Init()20 {21 NVIC_InitTypeDef NVIC_InitStructure;22 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中斷23 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //搶占 2 子優先級 3 組 224 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //搶占 2,子優先級 3,組 225 NVIC_Init(&NVIC_InitStructure); //NVIC 初始化26 }27 void WWDG_IRQHandler(void)28 {29 WWDG_SetCounter(WWDG_CNT);30 //當禁掉此句后,窗口看門狗將產生復位31 WWDG_ClearFlag();32 //清除提前喚醒中斷標志位33 LED1=!LED1;34 //LED 狀態翻轉35 }
主邏輯區代碼:
1 int main(void)2 {3 delay_init();//延時函數初始化4 NVIC_Configuration(); //設置 NVIC 中斷分組 25 usart1_init();串口1初始化6 LED_Init(); //LED 初始化7 KEY_Init(); //按鍵初始化8 LED0=0;9 delay_ms(500);10 WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//計數器值為 7f,窗口寄存器為 5f,//分頻數為 811 while(1)12 {13 LED0=1;14 }15 }
功能:
通過 LED0(DS0)來指示是否正在初始化。而 LED1(DS1)用來指示是否發生了中
斷。我們先讓 LED0 亮 300ms,然后關閉以用于判斷是否有復位發生了。在初始化 WWDG 之
后,我們回到死循環,關閉 LED1,并等待看門狗中斷的觸發/復位。
四 泛泛而談:
再來分析一下獨立看門狗(IWDG)和窗體看門狗(WWDG)的區別:
評論