本章介紹STM32F4**系列芯片的看門狗模塊內容
STM32F4**系列芯片具有兩個嵌入式看門狗外設,具有安全性高、定時准確及使用靈活的優點。兩個看門狗外設(獨立和窗口)均可用於檢測並解決由軟件錯誤導致的故障;當計數器達到給定的超時值時,觸發一個中斷(僅適用於窗口型看門狗)或產生系統復位。
獨立看門狗 (IWDG) 由其專用低速時鍾 (LSI) 驅動,因此即便在主時鍾發生故障時仍然保持工作狀態。窗口看門狗 (WWDG) 時鍾由 APB1 時鍾經預分頻后提供,通過可配置的時間窗 口來檢測應用程序非正常的過遲或過早的操作。
IWDG 最適合應用於那些需要看門狗作為一個在主程序之外,能夠完全獨立工作,並且對時 間精度要求較低的場合。WWDG 最適合那些要求看門狗在精確計時窗口起作用的應用程序。
1. 獨立看門狗(IWDG)
1.1 IWDG 主要特性
● 自由運行遞減計數器
● 時鍾由獨立 RC 振盪器提供(可在待機和停止模式下運行),默認32Khz,內部RC時鍾,時鍾周期並不准確,可在15~47Khz范圍內變化。
● 當遞減計數器值達到 0x000 時產生復位(如果看門狗已激活)
1.2 IWDG 寄存器
1.2.1 關鍵字寄存器 (IWDG_KR)
1.2.2 預分頻器寄存器 (IWDG_PR)
1.2.3 重載寄存器 (IWDG_RLR)
1.2.4 狀態寄存器 (IWDG_SR)
1.3 喂狗時間計算
Tout=((4×2^prer) ×rlr) /32,其中Tout為看門狗溢出時間(單位為ms);prer為看門狗時鍾預分頻值(IWDG_PR值),范圍為0~7;rlr為看門狗的重裝載值(IWDG_RLR的值)。比如我們設定prer值為4(4代表的是64分頻),rlr值為500,那么就可以得到Tout=64×500/32=1000ms,這樣,看門狗的溢出時間就是1s,只要在一秒鍾之內,有一次寫入0XAAAA到IWDG_KR,就不會導致看門狗復位(當然寫入多次也是可以的)。需要注意的是,看門狗的時鍾不是准確的32Khz,所以在喂狗的時候,最好不要太晚了,否則,有可能發生看門狗復位。
1.4 實驗代碼
實驗板在載入程序代碼后,因為沒有喂狗,每隔約1s左右時間會復位,造成LED燈閃爍,若按下KEY_UP按鍵,會觸發喂狗程序,連續按下后則不會再復位。
1 //初始化獨立看門狗 2 //prer:分頻數:0~7(只有低3位有效!) 3 //rlr:自動重裝載值,0~0XFFF. 4 //分頻因子=4*2^prer.但最大值只能是256! 5 //rlr:重裝載寄存器值:低11位有效. 6 //時間計算(大概):Tout=((4*2^prer)*rlr)/32 (ms). 7 void IWDG_Init(u8 prer,u16 rlr) 8 { 9 IWDG->KR=0X5555;//使能對IWDG->PR和IWDG->RLR的寫 10 IWDG->PR=prer; //設置分頻系數 11 IWDG->RLR=rlr; //從加載寄存器 IWDG->RLR 12 IWDG->KR=0XAAAA;//reload 13 IWDG->KR=0XCCCC;//使能看門狗 14 } 15 16 //喂獨立看門狗 17 void IWDG_Feed(void) 18 { 19 IWDG->KR=0XAAAA;//reload 20 } 21 22 int main(void) 23 { 24 Stm32_Clock_Init(360,25,2,8);//設置時鍾,180Mhz 25 delay_init(180); //初始化延時函數 26 LED_Init(); //初始化與LED連接的硬件接口 27 KEY_Init(); //初始化按鍵 28 delay_ms(100); //延時100ms再初始化看門狗,LED0的變化"可見" 29 IWDG_Init(4,500); //預分頻數為64,重載值為500,溢出時間為1s 30 LED0=0; //點亮LED0 31 while(1) 32 { 33 if(KEY_Scan(0)==WKUP_PRES)//如果WK_UP按下,則喂狗 34 { 35 IWDG_Feed();//喂狗 36 } 37 delay_ms(10); 38 }; 39 }
2. 窗口看門狗(WWDG)
2.1 WWDG 主要特性
窗口看門狗通常被用來監測由外部干擾或不可預見的邏輯條件造成的應用程序背離正常的運行序列而產生的軟件故障。遞減計數器的值在T6位(WWDG->CR)變成0 前被刷新,看門狗電路在達到預置的時間周期時,會產生一個Mcu復位。在遞減計數器達到窗口配置寄存器(WWDG->CFR)數值之前,如果7位遞減計數器的數值被刷新,那么也將產生一個Mcu復位。這表明遞減計數器需要在一個有限的時間窗口中被刷新。
2.2 WWDG 主要寄存器
2.2.1 控制寄存器 (WWDG_CR)
2.2.2 配置寄存器 (WWDG_CFR)
2.2.3 狀態寄存器 (WWDG_SR)
2.3 WWDG 配置要點
2.3.1 看門狗超時計算
最大超時設置:WWDG->CR |= 0x7F,最小超時設置:WWDG->CR |= 0x40
2.3.1 看門狗窗口值配置
如WWDG->CR |= 0x7F,WWDG->CFR |= 0x5F,則計數器在[0x7F,0x5F]的區間中不可刷新,否則會復位,在計數器區間[0x5F,0x40]需要配置。
2.4 WWDG 實驗測試
//保存WWDG計數器的設置值,默認為最大. u8 WWDG_CNT=0x7f; //初始化窗口看門狗 //tr :T[6:0],計數器值 //wr :W[6:0],窗口值 //fprer:分頻系數(WDGTB),僅最低2位有效 //Fwwdg=PCLK1/(4096*2^fprer). 一般PCLK1=45Mhz void WWDG_Init(u8 tr,u8 wr,u8 fprer) { RCC->APB1ENR|=1<<11; //使能wwdg時鍾 WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT. WWDG->CFR|=fprer<<7; //PCLK1/4096再除2^fprer WWDG->CFR&=0XFF80; WWDG->CFR|=wr; //設定窗口值 WWDG->CR|=WWDG_CNT; //設定計數器值 WWDG->CR|=1<<7; //開啟看門狗 MY_NVIC_Init(2,3,WWDG_IRQn,2);//搶占2,子優先級3,組2 WWDG->SR=0X00; //清除提前喚醒中斷標志位 WWDG->CFR|=1<<9; //使能提前喚醒中斷 } //重設置WWDG計數器的值 void WWDG_Set_Counter(u8 cnt) { WWDG->CR =(cnt&0x7F);//重設置7位計數器 } //窗口看門狗中斷服務程序 void WWDG_IRQHandler(void) { WWDG_Set_Counter(WWDG_CNT);//重設窗口看門狗的值! WWDG->SR=0X00;//清除提前喚醒中斷標志位 LED1=!LED1; } int main(void) { Stm32_Clock_Init(360,25,2,8);//設置時鍾,180Mhz delay_init(180); //初始化延時函數 LED_Init(); //初始化與LED連接的硬件接口 LED0=0; //點亮LED0 delay_ms(300); //延時300ms再初始化看門狗,LED0的變化"可見" WWDG_Init(0X7F,0X5F,3); //計數器值為7f,窗口寄存器為5f,分頻數為8 while(1) { LED0=1; //關閉LED0 }; }
測試程序中設置的計數器值為0x7F,窗口計數器為0x5F,分頻數為8,時鍾45MHz,最大復位時間約46ms。
測試程序使能了窗口看門狗中斷(計數器在0x40時觸發中斷),中斷中改變Led燈開關狀態,並且重設窗口看門狗的值,因此程序不會復位,看到的現象為LED0只開關一次,LED1每48ms閃速一次。