1. 程式人生 > >STM32 嵌入式學習入門 —— 視窗看門狗 & 獨立看門狗

STM32 嵌入式學習入門 —— 視窗看門狗 & 獨立看門狗

STM32的視窗看門狗 & 獨立看門狗


一、看門狗概述:
1.為什麼需要看門狗?
在由微控制器構成的微型計算機系統中,由於微控制器的工作常常會受到來自外界電磁場的干擾,造成程式的跑飛,而陷入死迴圈,程式的正常執行被打斷,由微控制器控制的系統無法繼續工作,會造成整個系統的陷入停滯狀態,發生不可預料的後果,所以出於對微控制器執行狀態進行實時監測的考慮,便產生了一種專門用於監測微控制器程式執行狀態的模組或者晶片,俗稱“看門狗”(watchdog) 。STM32內建兩個看門狗,提供了更高的安全性、時間的精確性和使用的靈活性。兩個看門狗裝置(獨立看門狗/視窗看門狗)可以用來檢測和解決由軟體錯誤引起的故障。當計數器達到給定的超時值時,觸發一箇中斷(僅適用視窗看門狗)或者產生系統復位。

2.看門狗解決的問題是什麼?
   ①在啟動正常執行的時候,系統不能復位;②在系統跑飛(程式異常執行)的情況,系統復位,程式重新執行。


3.獨立看門狗與視窗看門狗的區別?
(1)獨立看門狗(IWDG)由專用的低速時鐘(LSI)驅動,即使主時鐘發生故障它仍有效。獨立看門狗適合應用於需要看門狗作為一個在主程式之外能夠完全獨立工作,並且對時間精度要求低的場合。 (2)視窗看門狗由從APB1時鐘分頻後得到時鐘驅動。通過可配置的時間視窗來檢測應用程式非正常的過遲或過早操作。  視窗看門狗最適合那些要求看門狗在精確計時視窗起作用的程式。


==========下面分別介紹獨立看門狗和視窗看門狗的內容============

二、獨立看門狗(IWDG):
STM32 的獨立看門狗由內部專門的40Khz低速時鐘驅動,即使主時鐘發生故障,它也仍然有效。這裡需要注意獨立看門狗的時鐘是一個內部RC時鐘,所以並不是準確的40Khz,而是在30~60Khz之間的一個可變化的時鐘,只是我們在估算的時候,以40Khz的頻率來計算,看門狗對時間的要求不是很精確,所以,時鐘有些偏差,都是可以接受的。首先我們看一下看門狗的原理。這個百度百科裡面有很詳細的解釋。 總結如下:

看門狗的原理: 微控制器系統在外界的干擾下(比如磁場等)會出現程式跑飛的現象導致出現死迴圈,從而系統無法正常工作。 看門狗電路就是為了避免這種情況的發生而設計的。 看門狗的作用就是如果在一定時間內(通過定時計數器實現) 沒有接收喂狗訊號(表示MCU已經掛了),便實現處理器的自動復位重啟(傳送復位訊號),以實現系統的正常執行。看門狗就是定期檢查晶片內部程式執行情況,執行一旦發生錯誤就向晶片發出重啟訊號的電路。看門狗在程式的中斷中擁有最高的優先順序。
下面先了解幾個與獨立看門狗相關聯的暫存器之後講解怎麼通過庫函式來實現配置。首先是鍵值暫存器IWDG_KR,該暫存器的各位描述如下圖所示:


在鍵值暫存器(IWDG_KR)中寫入0xCCCC,開始啟用獨立看門狗;此時計數器開始從其復位值0xFFF遞減計數。當計數器計數到末尾0x000時,會產生一個復位訊號(IWDG_RESET)
無論何時,只要鍵暫存器
IWDG_KR中被寫入0xAAAA,IWDG_RLR中的值就會被重新載入到計數器中從而避免產生看門狗復位。
IWDG_PR IWDG_RLR 暫存器具有防寫功能。要修改這兩個暫存器的值,必須先向IWDG_KR暫存器中寫入0x5555。 將其他值寫入這個暫存器將會打亂操作順序,暫存器將重新被保護。重灌載操作(即寫入0xAAAA)也會啟動防寫功能。
還有兩個暫存器,一個預分頻暫存器(
IWDG_PR),該暫存器用來設定看門狗時鐘的分頻係數。 另一個重灌載暫存器。該暫存器用來儲存重灌載到計數器中的值。該暫存器也是一個32位暫存器,但是隻有低12位是有效的。只要對以上三個暫存器進行相應的設定,我們就可以啟動STM32的獨立看門狗,啟動過程可以按如下步驟實現 
1) 取消暫存器防寫(向IWDG_KR寫入0X5555),庫函式的實現是通過下面的函式呼叫實現的:
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
2)設定獨立看門狗的預分頻係數和重灌載值
設定看門狗的分頻係數的函式是:
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); //設定 IWDG 預分頻值
設定看門狗的重灌載值的函式是:
void IWDG_SetReload(uint16_t Reload); //設定 IWDG 重灌載值
設定好看門狗的分頻係數prer和重灌載值就可以知道看門狗的喂狗時間(也就是看門狗溢位時間),該時間的計算方式為:
Tout=((4×2^prer)×rlr) /40
其中 Tout為看門狗溢位時間(單位為ms);prer為看門狗時鐘預分頻值(IWDG_PR值),範圍為0~7rlr為看門狗的重灌載值(IWDG_
RLR的值)比如我們設定prer值為4rlr值為625,那麼就可以得到Tout=64×625/40=1000ms,這樣,看門狗的溢位時間就是1s, 只要你在一 秒鐘之內,有一次寫入0XAAAAIWDG_KR,就不會導致看門狗復位(當然寫入多次也是可以的)。這裡需要提醒大家的是,看門狗的時鐘不是準 確的40Khz,所以在喂狗的時候,最好不要太晚了,否則,有可能發生看門狗復位。
3) 過載計數值喂狗(向IWDG_KR寫入0XAAAA
庫函式裡面過載計數值的函式是:
IWDG_ReloadCounter(); //按照 IWDG 重灌載暫存器的值重灌載 IWDG 計數器
通過這句,將使STM32重新載入IWDG_RLR的值到看門狗計數器裡面。 即實現獨立看門狗的喂狗操作。
4)啟動看門狗(IWDG_KR寫入0XCCCC)
庫函式裡面啟動獨立看門狗的函式是:
IWDG_Enable(); //使能 IWDG
呼叫這個函式就啟動了STM32的看門狗。 注意IWDG在一旦啟用,就不能再被關閉!想要關閉,只能重啟,並且重啟之後不能開啟IWDG,否則問 題依舊,所以如果不用IWDG的話,就不要去開啟它,免得麻煩。
通過上面4個步驟,我們就可以啟動STM32的看門狗了,使能了看門狗,在程式裡面就必須間隔一定時間喂狗,否則將導致程式復位。比如我們可 用LED燈的長亮表示程式在正常執行,用LED燈的閃爍表示程式產生復位(即程式被重新裝載後LED燈會閃爍一下)。



三、視窗看門狗的原理(WWDG):
視窗看門狗的原理與獨立看門狗一致,之所以稱之為視窗看門狗就是因為其喂狗時間是一個有上下限的範圍(視窗),我們可以通過設定相關寄存 器,設定其上限時間(下限固定),喂狗的時間不能過早也不能過晚,應該在下限時間(固定值)— 上限時間(可自己設定)之間,這裡注意自己 設定的上限時間應大於下限時間。而獨立看門狗限制喂狗時間在0-x內,x由相關暫存器決定。無論是獨立看門狗還是視窗看門狗,喂狗的時間不能過 晚。 下圖是視窗看門狗的工作示意圖:


接下來,介紹和視窗看門狗相關的3個暫存器。 1.控制暫存器(WWDG_CR),該暫存器的各位描述如下圖所示:

WWDG_CR 只有低八位有效,T[60]用來儲存看門狗的計數器值,隨時更新的,每個視窗看門狗計數週期(4096×2^WDGTB)減1。當該計數器的值從0X40變為0X3F的時候,將產生看門狗復位。
WDGA 位則是看門狗的啟用位,該位由軟體置1,以啟動看門狗,並且一定要注意的是該位一旦設定,就只能在硬體復位後才能清零了。

2.配置暫存器(WWDG_CFR),該暫存器的各位及其描述如圖所示:


該位中的 EWI是提前喚醒中斷,也就是在快要產生復位的前一段時間(T[6:0]=0X40) 來提醒我們,需要進行喂狗了,否則將復位!因此,我們一般用該位來設定中斷,當視窗看門狗的計數器值減到0X40的時候,如果該位設定,並開啟了中斷,則會產生中斷,我們可以在中斷裡面向WWDG_CR重新寫入計數器的值,來達到喂狗的目的。注意這裡在進入中斷後, 必須在不大於1個視窗看門狗計數週期的時間(在PCLK1頻率為36M WDGTB0的條件下,該時間為113us)內重新寫WWDG_CR,否則,看門狗將產生復位!
3.狀態暫存器(WWDG_SR),該暫存器用來記錄當前是否有提前喚醒的標誌。該暫存器僅有位0有效,其他都是保留位。當計數器值達到40h時,此位由硬體置1。它必須通過軟體寫0來清除。對此位寫1無效。 即使中斷未被使能, 在計數器的值達到0X40的時候, 此位也會被置1


四、啟用視窗看門狗:
下面介紹通過使用庫函式的方法啟用視窗看門狗的步驟。 1) 使能WWDG時鐘:
WWDG 不同於 IWDGIWDG有自己獨立的 40Khz 時鐘,不存在使能問題。而 WWDG使用的是PCLK1的時鐘,需要先使能時鐘。呼叫下面的函式即可:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 時鐘使能
2) 設定視窗值和分頻數
設定視窗值的函式如下,
這個函式的入口引數 WindowValue 用來設定看門狗的上視窗值。
void WWDG_SetWindowValue(uint8_t WindowValue);
設定分頻數的函式如下,這個函式同樣只有一個入口引數,用來設定看門狗的分頻值
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
3) 開啟WWDG中斷並分組開啟 WWDG 中斷的函式為:
WWDG_EnableIT(); //開啟視窗看門狗中斷 
4) 設定計數器初始值並使能看門狗,這一步在庫函式裡面是通過一個函式實現的:
void WWDG_Enable(uint8_t Counter);
該函式既設定了計數器初始值,同時使能了視窗看門狗。
完成了以上 個步驟之後,我們就可以使用 STM32 的視窗看門狗了。
在最後,如果想使用中斷服務函式,就要編寫視窗看門狗的中斷服務函式,通過該函式來喂狗,比如可以通過按鍵來喂狗,通過LED燈來指示程式執行的情況。注意喂狗要快,否則當視窗看門狗計數器值減到
0X3F的時候,就會引起軟復位了。在中斷服務函式裡面也要將狀態暫存器的EWIF位清空。