昨天件紹了看們狗的,今天就來看看如何使用看門狗
獨立看門狗一般用來檢測和解決由程式引起的故障,比如一個程式正常運行的時間是50ms,在運行完這個段程式之後緊接著進行喂狗,我們設置獨立看門狗的定時溢出時間為60ms,比我們需要監控的程式50ms 多一點,如果超過60ms 還沒有喂狗,那就說明我們監控的程序出故障了,那麼就會產生系統重置,讓程式重新運行。
接下來做1個簡單的超過預定時間的實驗
硬體:IWDG、按鈕 1個、LED 1個
IWDG屬於MCU內部資源,不需要外部電路,需要一個外部的按鍵和LED,通過按鍵來喂狗,喂狗成功LED 亮,喂狗失敗,程式重啟,LED 滅一次。
軟體:我們編寫兩個 IWDG 驅動檔,bsp_iwdg.h 和 bsp_iwdg.c,用來IWDG的初始化配置函數。
#ifndef __IWDG_H
#define __IWDG_H
#include "stm32f0xx.h"
void IWDG_Config(uint8_t prv ,uint16_t rlv);
void IWDG_Feed(void);
#endif /* __IWDG_H */
宣告初始化函式和IWDG實驗函式
#include "./iwdg/bsp_iwdg.h"
void IWDG_Config(uint8_t prv ,uint16_t rlv)
{
IWDG_WriteAccessCmd( IWDG_WriteAccess_Enable ); // 致能預分頻寄存器PR和重新加載暫存器RLR可寫入
IWDG_SetPrescaler(prv); // 設置預分頻器值
IWDG_SetReload(rlv); // 設置重新加載暫存器值
IWDG_ReloadCounter(); // 把重新加載暫存器的值放到計數器中
IWDG_Enable(); // 使能 IWDG
}
// 喂狗
void IWDG_Feed(void)
{
// 把重新加載暫存器的值放到計數器中,喂狗,防止IWD重置
// 當計數器的值減到0的時候會產生系統重定
IWDG_ReloadCounter();
}
以上式兩個函式的實現,再來看看主程式如何實現這兩個函式
#include "stm32f0xx.h"
#include "./led/bsp_led.h" //GPIO初始化來點亮LED
#include "./key/bsp_key.h" //GPIO初始化來檢測按鍵狀態
#include "./iwdg/bsp_iwdg.h" //看門口初始話
int main(void)
{
LED_GPIO_Config(); // GPIO_LED初始化
Delay_ms(20);
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) //檢查是否為獨立看門狗重置
{
LED_RED; //獨立看門狗復位,亮紅燈
RCC_ClearFlag(); //清除標誌
/*如果一直不喂狗,會一直復位,加上前面的延時,會看到紅燈閃爍
在1s 時間內喂狗的話,則會持續亮綠燈*/
}
else
{
//不是獨立看門狗復位(可能為上電重定或者手動按鍵重定之類的)
LED_BLUE; //亮藍燈
}
/*初始化按鍵*/
Key_GPIO_Config();
// IWDG 1s 超時溢出
IWDG_Config(IWDG_Prescaler_64 ,625);
while(1)
{
if( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON )
{
// 喂狗,如果不喂狗,系統則會重定,重定後亮紅燈,如果在1s
// 時間內準時喂狗的話,則會亮綠燈
IWDG_Feed();
//喂狗後亮綠燈
LED_GREEN;
}
}
}
while部分是我們在專案中具體需要寫的代碼,這部分的程式可以用獨立看門狗來監控如果我們知道這部分代碼的執行時間,比如是500ms,那麼我們可以設置獨立看門狗的溢出時間是600ms,比500ms多一點,如果要被監控的程式沒有跑飛正常執行的話,那麼執行完畢之後就會執行喂狗的程式,如果程式跑飛了那程式就會超時,到達不了喂狗的程式,此時就會產生系統重定。但是也不排除程式跑飛了又跑回來了,剛好喂狗了,歪打正著。所以要想更精確的監控程序,可以使用視窗看門狗,視窗看門狗規定必須在規定的視窗時間內喂狗。
明天就會來看看視窗看門狗的簡介和用法了。