看門狗定時器(WDT,Watch Dog Timer)是單片機的一個組成部分,它實際上是一個計數器,一般來說都是向下計數的,給看門狗一個數字,程序開始運行后看門狗開始倒計數。如果程序運行正常,過一段時間CPU應發出指令讓看門狗復位(在計數器減到0之前),重新開始倒計數。如果看門狗減到0就認為程序沒有正常工作,強制整個系統復位。本節將對看門狗定時器的工作原理和作用進行詳細講解。
看門狗的主要功能是在發生系統軟件故障時,將系統復位。也可以用于將系統從休眠或空閑模式喚醒。一般在嵌入式開發中,整個程序都是在次循環往復不停的工作,正常運行期間會定時讓看門狗復位,一旦程序發生故障,停在某一處,看門狗不能及時復位,計數器減到0,就會強制整個系統復位,一般情況下復位操作能解決大部分問題。
用戶開發的產品很有可能運用到一些非常極端苛刻的環境中,容易發生故障,但是通過復位就能解決,如果人工復位,成本相當高,這時候看門狗的使用就非常有效了。
STM32結合安全度、計時精確度和易用性提供了IWDG和WWDG兩種看門狗,監測軟件跑飛,或未按預想地運行的情況觸發系統復位或產生中斷(中斷僅針對窗口看門狗)
獨立看門狗IWDG:專用時鐘LSI(內部低速時鐘),低功耗模式仍可運行,對定時的控制比較松,由于專門為其提供獨立的時鐘,因此稱為獨立看門狗。
窗口看門狗WWDG:總線時鐘APB1,對定時控制比較嚴,要求主應用程序在規定時間窗口內喂狗。
獨立看門狗IWDG工作原理框圖分析
獨立看門狗本質上就是一個計數定時器,既然是定時器,就和普通定時器的工作原理差不多,仍然包含計數器,重裝載寄存器等關鍵部件。計數器遞減的速度取決于時鐘的頻率,獨立看門狗使用專用內部低速時鐘,大小為32KHz。當計數器減到0后會觸發一個復位異常,進行系統的重啟。為了不讓計數器減到0,在程序中每過一段時間都要進行喂狗操作,喂狗操作就是刷新遞減計數器CNT的值,就是把重裝載值再次刷進計數器中。狀態寄存器是用來指示預分頻器和重載寄存器更新的狀態。
1.獨立看門狗的時鐘:STM32F4 的獨立看門狗由內部專門的 32Khz 低速時鐘(LSI)驅動,即使主時鐘發生故障,它也仍然有效。這里需要注意獨立看門狗的時鐘是一個內部RC時鐘(RC振蕩器典型的缺陷就是比較容易受環境的影響,且精確地不高),所以并不是準確的32Khz,而是在 15~47Khz 之間的一個可變化的時鐘,只是我們在估算的時候(之所以要估算時間是因為用戶要確保計數器減到0 之前喂狗),以 32Khz 的頻率來計算,看門狗對時間的要求不是很精確,所以,時鐘有些偏差,都是可以接受的。
2.預分頻器:分頻之后的時鐘才是真正驅動遞減計數器的時鐘。寄存器中只有低3位有效,不同的位組合表示不同的分頻系數。
3.重載寄存器:低12位有效,最大值位2的12次方。只有在關鍵字寄存器中寫入AAAAh時,重載寄存器厚葬的值才會自動裝載到看門狗計數器中。
4.關鍵字寄存器:用來控制獨立看門狗,寫入不同的值執行不同的命令。正常情況下PR和PLR是不可寫的,具有寫保護,需要通過寫入關鍵字寄存器值來解除寫保護。另外一旦通過關鍵字寄存器啟動看門狗,看門狗計數,將不會再停止,除非硬件復位,默認情況下看門狗關閉,所以正常情況下不輕易使用看門狗,否則系統會產生出乎意料的復位,造成損失。
5.狀態寄存器:低2位有效,更新時一定要確定相應位為0才可以更新。
IWDG的超時時間
以預分頻器分頻系數為32為例,計數器的時鐘頻率為1KHz,每個脈寬的時間間隔為1ms,當計數器的值為最小值1時,則最短超時時間為1ms,當當計數器的值為最大值0xFFF時,最長超時時間為2的12次方乘以1ms為4096ms。因此用戶可根據下表設置正確的超時時間防止看門狗復位。
IWDG獨立看門狗實例
實驗要求:開啟STM32的獨立看門狗,按鍵按下即喂狗,如果超時未喂狗,則看門狗復位系統,用指示燈指示系統復位。
步驟:
1.配置RCC
2.使能并配置IWDG
3.配置按鍵管腳為輸入模式。
4.編寫代碼
//mian.c
#include "main.h"
#include "stm32f4xx_hal.h"
#include "iwdg.h"
#include "usart.h"
#include "gpio.h"
int main(){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_IWDG_Init();
printf("this is iwdg testn");
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET);//默認指示燈熄滅
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET);
//指示燈亮,如果系統復位,指示燈就會熄滅0.5s后再次亮起
while(){
//********************************
//********************************
//********************************
//正常情況下喂狗操作之前有很多用戶程序
//現在使用按鍵手動喂狗以便觀察現象
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) {
HAL_IWDG_Refresh(&hiwdg);
//喂狗操作,將重載計數器的值再次裝填到計數器中 ,防止復位 }
}
}
窗口看門狗WWDG剖析
窗口看門狗(WWDG)通常被用來監測由外部干擾或不可預見的邏輯條件造成的應用程序背離正常的運行序列而產生的軟件故障。
遞減計數器的值在 T6 位(WWDG->CR 的第六位)變成 0 前被刷新,看門狗電路在達到預置的時間周期時,會產生一個 MCU 復位。WWDG->CR滿載時為1111111,即0x7F,滿載隨著時鐘減1,當減到1000000,即0x40時,如果再減1變為0x3F之前計數器沒有被刷新(喂狗),則會產生 MCU 復位。由0x40變為0x3F第六為由1變為0,也就是第6為變為0之前計數器必須被刷新。0x40就是下窗口
在遞減計數器達到窗口配置寄存器(WWDG->CFR)數值之前,如果 7 位的遞減計數器數值(在控制寄存器中)被刷新, 那么也將產生一個 MCU 復位。也就是計數器在減到窗口配置寄存器(WWDG->CFR)中設定的數值之前被刷新(喂狗),就會就會產生 MCU 復位。這個數值就是上窗口
二者分別設定了一個喂狗的時間下限和一個喂狗的時間上限,中間形成了一個喂狗的窗口,因而稱為窗口看門狗。這樣對喂狗的時間有了更加精確的定位,要求也更嚴格。
WWDG的特性
可配置的時間窗,用來檢測應用程序非預期中的運行流程(過早或過晚),上窗口的值可配置范圍為0x40-0x7F(64-127)
看門狗復位條件:①使能了看門狗的情況下,自減計數器值小于0x40。② 使能了看門狗的情況下,喂狗時間大于上窗口的值
計數器值=0x40時可以使能一個早期喚醒中斷(EWI),因為再減下去即將產生復位,如果有些數據還不保存就來不及了,可以在中斷處理中做一些緊急保護的事情或者刷新看門狗計數器。
窗口看門狗WWDG工作原理框圖分析
①窗口看門狗時鐘:窗口看門狗時鐘來自 PCLK1,也就是來自APB1,是主系統時鐘,PCLK1 最大是 42M,由 RCC 時鐘控制器開啟。一旦主系統時鐘崩潰,窗口看門狗就無法工作。
②計數器時鐘:計數器時鐘由 CK計時器時鐘經過預分頻器分頻得到,WDG分頻器仍然有一些分頻系數供用戶選擇,分頻系數由配置寄存器 CFR 的位 8:7 WDGTB[1:0]配置。
③計數器:窗口看門狗的計數器是一個遞減計數器,共有 7 位,其值存在控制寄存器CR 的位 6:0,即 T[6:0],當 7 個位全部為 1時是 0X7F,這個是最大值,當遞減到 T6 位變成 0時,即從0X40 變為 0X40時候,會產生看門狗復位。這個值 0X40 是看門狗能夠遞減到的最小值,當遞減計數器遞減到 0X40 的時候,還不會馬上產生復位,如果使能了提前喚醒中斷:CFR 位 9 EWI 置 1,則產生提前喚醒中斷,如果真進入了這個中斷的話,就說明程序肯定是出問題了,那么在提前喚醒中斷的處理程序中我們就需要做最重要的工作,比如保存重要數據,或者報警等,這個中斷我們也叫它死前中斷。但是這個中斷的處理時間只有0X40減到0X3F的一個CLK的時長。
④窗口值:下窗口的值是固定的0X40,上窗口的值可以改變,具體的由配置寄存器CFR 的位 6:0 W[6:0]設置。其值必須大于 0X40(十進制為64),如果小于或者等于 0X40就是失去了窗口的價值,而且也不能大于計數器的值,所以必須得小于 0X7F(十進制為127)。如何設置窗口值需要根據我們需要監控的程序的運行時間來決定。如果我們要監控的程序段 A 運行的時間為 Ta,當執行完這段程序之后就要進行喂狗,如果在窗口時間內沒有喂狗的話,那程序就肯定是出問題了。一般計數器的值TR設置成最大 0X7F,窗口值為 WR,計數器減一個數的時間為 T,那么時間:(TR-WR)*T 應該稍微小于 Ta即可。
窗口看門狗WWDG實例
實驗要求:開啟STM32的窗口看門狗,并使能喚醒中斷。主程序正常運行時喂狗,用按鍵中斷模擬程序故障死機,此時將觸發喚醒中斷并產生復位,用LED燈指示喚醒中斷的觸發。
達到0X40會觸發早期喚醒中斷,但是再次減1就會產生系統復位,因此中斷處理的事件就是1個CLK的持續時間,不同的分頻系數,CLK的持續時間不同,總體來說早期喚醒中斷的時間事件相當短,這個過程中只能做一些非常緊急的操作。
步驟:
1.配置RCC
2.配置LED燈管腳,設為輸出模式
3.配置按鍵中斷管腳,設為外部中斷模式
4.使能并配置WWDG
5.中斷配置
6.編寫代碼
//main.c
#include "main.h"
#include "stm32f4xx_hal.h"
#include "usart.h"
#include "wwdg.h"
#include "gpio.h"
int main(){
uint8_t wr, tr;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_WWDG_Init();
printf("this is wwdg testn");
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET);//初始時指示燈熄滅
wr = WWDG- >CFR & 0x7f ;//獲取上窗口的值
while(){
tr = WWDG- >CR & 0x7f;//獲取當前計數器的值
if(tr < wr){ //計數器的值小于上窗口的值,進行喂狗
//沒有復位說明大于下窗口的值,不需要判斷
HAL_WWDG_Refresh(&hwwdg); //刷新計數器的值,喂狗
}
}
}
//gpio.c
//重寫按鍵中斷(外部中斷)的中斷處理回調函數
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == GPIO_PIN_0) {
printf("程序故障n");
while(1); //死循環,模擬故障死機
}
}
//wwdg.c
//重寫提前喚醒中斷的中斷處理回調函數
void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg) {
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET); //LED亮
printf("EarlyWakeup INTn");
//提前喚醒中斷處理的時間非常有限,串口信息很有可能打印不完整
}
-
看門狗定時器
+關注
關注
0文章
38瀏覽量
16243 -
STM32F4
+關注
關注
3文章
194瀏覽量
27991 -
狀態寄存器
+關注
關注
0文章
38瀏覽量
7073 -
WWDG
+關注
關注
0文章
19瀏覽量
5500 -
IWDG
+關注
關注
0文章
21瀏覽量
5195
發布評論請先 登錄
相關推薦
評論