STM32F1小白系列之四、獨立看門狗(IWDG)
阿新 • • 發佈:2019-02-08
一、看門狗原理
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);
};
}
五、備註
本程式基本是完全照抄正點原子的程式,因為是看了一遍原子哥的程式,然後關掉自己重新寫的,所以一些語句可能不同,但是思路完全一樣,所以想要原版程式的童鞋可以直接去正點原子論壇找找原版。