1. 程式人生 > >STM32F1小白系列之四、獨立看門狗(IWDG)

STM32F1小白系列之四、獨立看門狗(IWDG)

一、看門狗原理

1、微控制器中有一個【暫存器(計數器)】專門用來倒計數,這個計數器倒計數是獨立於程式之外的,不受程式影響的。(程式是井,計數器是河,井水不犯河水,你跑你的程式,我記我的數,互不影響。)

2、但是:
這個【計數器】會有一個初值,這個值會逐次遞減,終有一刻會自減到0,當計數自減到0的時候,【系統】就會強制重啟,程式會從頭開始執行。
而當計數器每次倒計數到0之前,如果往計數器裡面重新寫入一次數值,他就永遠不會倒計數到0,這時候系統也就不會重啟了。

3、所以:
程式設計師寫程式的時候,如果開啟了看門狗,會在程式中實現這樣一個功能——專門設定固定的時間迴圈往復的往【計數器】中寫入一個數值(喂狗)

當程式正常執行的時候,每隔一段時間,【計數器】會被重新寫入數值,那麼它永遠不會倒計時到0,
而當程式跑飛或者系統卡死,程式不能按照預想的要求來執行,也就不能在設定的時間去喂狗,那麼計數器肯定會有一個時刻倒計數到0,系統就會重啟,程式就會從頭開始跑,又恢復到初始執行狀態。

4、所以:
看門狗的作用就是——不用人為的檢查程式是否正常執行,系統是否正常執行,需不需要重啟系統,如果程式跑飛或者系統卡死,則自動重新啟動系統,而不要人為的主動去重新啟動系統

二、看門狗相關暫存器

1、 鍵值暫存器 IWDG_KR
2、 預分頻暫存器 IWDG_PR
3、 重灌載暫存器 IWDG_RLR
4、 狀態暫存器 IWDG_SR

三、配置看門狗步驟

1、使能暫存器可寫入(即:關閉防寫)
    向【鍵值暫存器(IWDG_KR)】寫入【0xAAAA】即可使【預分頻暫存器】和【重灌載暫存器】變得可以寫入資料。

2、配置預分頻值
    資料位[2:0]。
    預分頻因子:4/8/16/32/64/128/256

3、配置重灌載值
    資料位[11:0].

4、重新裝載一次計數值(喂狗一次)

5、啟動看門狗

四、看門狗程式

1、使用庫函式

1)相關庫函式

1 關閉防寫 IWDG_WriteAccessCmd();
2 配置預分頻值 IWDG_SetPrescaler();
3 配置重灌載值 IWDG_SetReload();
4 重新裝載計數器 IWDG_ReloadCounter();
5 使能看門狗(啟動看門狗) IWDG_Enable();

2)程式

/*
    函式功能:初始化獨立看門狗
    函式名:init_iwdg
    返回值:void
    引數:  pre_scaler_value   預分頻值
           reload_value       重灌載數值
 */
void init_iwdg(uint8_t pre_scaler_value, uint32_t reload_value)
{
    IWDG_WriteAccessCmd(0x5555);//關閉防寫:IWDG->KR = 0x5555;

    IWDG_SetPrescaler(pre_scaler_value);//分頻因子為4,引數由main函式傳參傳進來,預分頻值為64,(4==100),   IWDG->PR = 4, 即:IWDG->PR的bit[2]bit[1]bit[0]分別為100

    IWDG_SetReload(reload_value);//配置重灌載值,引數由main函式傳參傳進來,3秒,公式:T(ms) == [(4 * 2^pre_Scaler) * reload] / 40;

    IWDG_ReloadCounter();//第一次喂狗

    IWDG_Enable();//使能看門狗
}

//喂狗API
void feed_iwdg(void)
{
    IWDG_ReloadCounter();//喂狗,使STM32重新載入【IWDG_RLR中的值】到【看門狗計數器裡面】。
}

2、直接配置暫存器

/*
    函式功能:初始化獨立看門狗
    函式名:init_iwdg
    返回值:void
    引數:  pre_scaler_value   預分頻值
           reload_value       重灌載數值
 */
void init_iwdg(uint8_t pre_scaler_value, uint32_t reload_value)
{
    /*配置暫存器*/
    IWDG->KR = 0x5555;  //關閉防寫,可以向IWDG_PR和IWDG_RLR暫存器中寫入資料。
    IWDG->PR = pre_scaler_value;        //配置預分頻因子,4 == 0100,表示與分頻因子為64
    IWDG->RLR = reload_value;               //配置重灌載值,公式:T(ms) == [(4 * 2^pre_Scaler) * reload] / 40;

    /*初始化喂狗一次*/
    IWDG->KR = 0xAAAA;  //第一次喂狗。

    /*啟動看門狗*/
    IWDG->KR = 0xCCCC;  
}

//喂狗API
void feed_iwdg(void)
{
    IWDG->KR = 0xAAAA;//喂狗,使STM32重新載入【IWDG_RLR中的值】到【看門狗計數器裡面】。
}

3、main函式

因為暫存器版本和庫函式版本只是初始化配置函式不同,不影響main函式,所以main函式是一樣的。
main函式中主要實現的功能就是:

  • while迴圈檢測是否有按鍵按下,若有,則喂狗

程式如下:

 int main(void)
 {      
    delay_init();            //延時函式初始化    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //設定NVIC中斷分組2:2位搶佔優先順序,2位響應優先順序
    LED_Init();          //初始化與LED連線的硬體介面
    KEY_Init();          //按鍵初始化     
    delay_ms(500);       //延時

    init_iwdg(4,1875);   //初始化看門狗
    LED0=0;              //點亮LED0
    while(1)
    {
        if (KEY_Scan(1))//迴圈檢測,當按下任何一個按鍵就喂狗一次
        {
            feed_iwdg();
        }
        delay_ms(10);
    };   
}

五、備註

本程式基本是完全照抄正點原子的程式,因為是看了一遍原子哥的程式,然後關掉自己重新寫的,所以一些語句可能不同,但是思路完全一樣,所以想要原版程式的童鞋可以直接去正點原子論壇找找原版。