
為什么要看門狗?在單片機(jī)構(gòu)成的微型計(jì)算機(jī)系統(tǒng)中,由于單片機(jī)的工作容易受到來自外界電磁場(chǎng)的干擾,導(dǎo)致程序跑飛,陷入死循環(huán),程序的正常運(yùn)行被打斷,由單片機(jī)控制的系統(tǒng)無法繼續(xù)工作,會(huì)造成整個(gè)系統(tǒng)的陷入停滯狀態(tài),發(fā)生不可預(yù)料的后果。 所以出于對(duì)單片機(jī)運(yùn)行狀態(tài)進(jìn)行實(shí)時(shí)監(jiān)測(cè)的考慮,便產(chǎn)生了一種專門用于監(jiān)測(cè)單片機(jī)程序運(yùn)行狀態(tài)的模塊或者芯片,俗稱“看門狗”(watchdog) 。 在啟動(dòng)正常運(yùn)行的時(shí)候,若系統(tǒng)不能復(fù)位,或者在系統(tǒng)跑飛(程序異常執(zhí)行)的情況下,看門狗可以觸發(fā)系統(tǒng)復(fù)位,程序重新執(zhí)行。 STM32F10x看門狗STM32F10x 內(nèi)置 兩個(gè)看門狗 提供了更高的安全性、時(shí)間的精確性和使用的靈活性。 兩個(gè)看門狗設(shè)備(獨(dú)立看門狗和窗口看門狗)可用來檢測(cè)和解決由軟件錯(cuò)誤引起的故障;當(dāng)計(jì)數(shù)器達(dá)到給定的超時(shí)值時(shí),觸發(fā)一個(gè)中斷(僅適用于窗口型看門狗)或產(chǎn)生系統(tǒng)復(fù)位。 獨(dú)立看門狗(IWDG)由專用的低速時(shí)鐘(LSI)驅(qū)動(dòng),即使主時(shí)鐘發(fā)生故障它也仍然有效。 窗口看門狗由從APB1時(shí)鐘分頻后得到的時(shí)鐘驅(qū)動(dòng),通過可配置的時(shí)間窗口來檢測(cè)應(yīng)用程序非正常的過遲或過早的操作。 看門狗應(yīng)用場(chǎng)景 獨(dú)立看門狗使用專用的低速時(shí)鐘(LSI)驅(qū)動(dòng)),適合應(yīng)用于需要看門狗作為一個(gè)在主程序之外 能夠完全獨(dú)立工作,并且對(duì)時(shí)間精度要求低的場(chǎng)合。 窗口看門狗從APB1時(shí)鐘分頻后得到時(shí)鐘驅(qū)動(dòng),最適合那些要求看門狗在精確計(jì)時(shí)窗口起作用的程序。
獨(dú)立看門狗1、獨(dú)立看門狗基本原理在鍵值寄存器(IWDG_KR)中寫入0xCCCC,開始啟用獨(dú)立看門狗。 此時(shí)計(jì)數(shù)器開始從其復(fù)位值0xFFF遞減,當(dāng)計(jì)數(shù)器值計(jì)數(shù)到尾值0x000時(shí)會(huì)產(chǎn)生一個(gè)復(fù)位信號(hào)(IWDG_RESET)。 無論何時(shí),只要在鍵值寄存器IWDG_KR中寫入0xAAAA(通常說的喂狗), 自動(dòng)重裝載寄存器IWDG_RLR的值就會(huì)重新加載到計(jì)數(shù)器,從而避免看門狗復(fù)位。 如果程序異常,就無法正常喂狗,從而系統(tǒng)復(fù)位

2、獨(dú)立看門狗計(jì)時(shí)周期時(shí)鐘頻率為40khz,若選擇: 預(yù)分頻 4 ,重轉(zhuǎn)載值0xFFF 最長(zhǎng)時(shí)間:1s / (40000hz /4) * 0x1000 * 1000 = 409.6ms
 3、獨(dú)立看門狗配置步驟取消寄存器寫保護(hù):0x5555使能 void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); 設(shè)置獨(dú)立看門狗的預(yù)分頻系數(shù),確定時(shí)鐘,寫PR void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); 設(shè)置重裝載值:確定溢出時(shí)間,寫RLR void IWDG_SetReload(uint16_t Reload); 使能看門狗:寫0xCCCC到KR void IWDG_Enable(void); 喂狗:寫0xAAAA到KR void IWDG_ReloadCounter(void); 獲取狀態(tài):重裝載/預(yù)分頻 更新 FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);
4、獨(dú)立看門狗代碼部署
5、獨(dú)立看門狗測(cè)試?yán)?/h6>代碼部署如下: 喂狗標(biāo)志為0時(shí),不執(zhí)行喂狗,系統(tǒng)一直復(fù)位; 喂狗標(biāo)志不為0時(shí),執(zhí)行喂狗,系統(tǒng)正常運(yùn)行; int sign; //喂狗標(biāo)記
int main(void)
{
IWDG_Init(4,625); //與分頻數(shù)為64,重載值為625,溢出時(shí)間為1s
while(1)
{
if(sign != 0)
{
IWDG_Feed();//如果WK_UP按下,則喂狗
}
};
} 在初始化處打斷點(diǎn), 設(shè)置sign = 0時(shí),每個(gè)一秒重新執(zhí)行初始化; 再設(shè)置sign = 3時(shí),不重新初始化,正常運(yùn)行; 重新設(shè)置sign = 0時(shí),重新執(zhí)行初始化;
 窗口看門狗1、窗口看門狗概念窗口看門狗,之所以稱為窗口是因?yàn)槠湮构窌r(shí)間是一個(gè)有上下限的范圍(窗口),喂狗的時(shí)間不能過早也不能過晚。(上限:0x7FH-0x40H,下限:0x3FH,若上限值小于0x3FH,則無窗口直接復(fù)位 )

 使用窗口看門狗,可以根據(jù)預(yù)測(cè)的程序正常執(zhí)行的時(shí)間設(shè)置刷新看門狗的時(shí)間窗口,保證不會(huì)提前刷新看門狗也不會(huì)滯后刷新看門狗,就可以檢測(cè)程序是否正常運(yùn)行,非正常地跳過某些程序段的情況。 2、窗口看門狗觸發(fā)條件當(dāng)喂狗的時(shí)候如果計(jì)數(shù)器的值大于某一設(shè)定數(shù)值W[6:0]時(shí),此設(shè)定數(shù)值在WWDG_CFR寄存器定義。 當(dāng)計(jì)數(shù)器的數(shù)值從0x40減到0x3F時(shí)【T6位跳變到0】
3、窗口看門狗計(jì)時(shí)周期PCLK1 = 36MHZ,若WDGTB = 0,則: 最長(zhǎng)時(shí)間:1000ms / (36000000hz) * 4096 * 2 o * (0x3F +1) = 7.2818ms
 4、窗口看門狗配置步驟使能看門狗時(shí)鐘 RCC_APB1PeriphClockCmd(); 設(shè)置分頻系數(shù) WWDG_SetPrescaler(); 設(shè)置上窗口值 WWDG_SetWindowValue(); 開啟提前喚醒中斷并分組(可選) WWDG_EnableIT(); NVIC_Init(); 使能看門狗 WWDG_Enable(); 喂狗 WWDG_SetCounter(); 編寫中斷服務(wù)函數(shù) WWDG_IRQHandler();
5、窗口看門狗代碼部署

6、測(cè)試現(xiàn)象如下:注釋 main 中 while 內(nèi)的喂狗部分代碼,通過 “Record”獲取喂狗計(jì)數(shù)值。 “WWDG_IRQHandler” 在計(jì)數(shù)值為 0x40時(shí)觸發(fā)。 由于監(jiān)視窗口刷新問題,可知 “Record”至少為 266369 ;

 則開放 main 中 while 內(nèi)的喂狗部分代碼,將“sign”設(shè)為50000(小于Record值,沒有標(biāo)準(zhǔn)計(jì)時(shí),故測(cè)試了幾個(gè)值,需要保證喂狗時(shí),看門狗計(jì)數(shù)值在窗口值與0x3F之間,選擇合適的50000),進(jìn)行喂狗,則不觸發(fā)看門狗中斷,也不進(jìn)行復(fù)位。此時(shí)修改sign為20000,過早喂狗,相當(dāng)于程序運(yùn)行不正常,系統(tǒng)復(fù)位初始化;
 結(jié)合上兩個(gè)實(shí)驗(yàn),在窗口值與0x3FH之間進(jìn)行喂狗,才可以保證程序正常運(yùn)行;程序異常,導(dǎo)致過早或過晚喂狗,那么系統(tǒng)進(jìn)行復(fù)位。
|