一、看門狗概述
1、為什么要看門狗
在由單片機構成的微型計算機系統中,由于單片機的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛。而陷入死循環,程序的正常運行被打斷,由單片機控制的系統無法繼續工作,會造成整個系統陷入停滯狀態,發生不可預料的后果,所以出于對單片機運行狀態進行實時監測的考慮,便產生了一種專門用于監測單片機程序運行狀態的模塊或者芯片,俗稱“看門狗”(watchdog)。
2、看門狗解決的問題是什么
在啟動正常運行的時候,系統不能復位。在系統跑飛(程序異常執行)的情況下,系統復位程序重新執行。
明白了,所以就要每過一段時間喂狗,如果超過該時間段還沒有進行喂狗程序,將視為程序跑飛,則系統看門狗復位。
二、STM32看門狗
STM32內置兩個看門狗,提供了更高的安全性,時間的精確性和使用的靈活性。兩個看門狗設備(獨立看門狗和窗口看門狗)可以用來檢測和解決由軟件錯誤引起的故障。當計數器達到給定的超時值是,觸發一個中斷(僅適用窗口看門狗)或者產生系統復位。
獨立看門狗(IWDG):
由專用的低速時鐘(LSI)驅動,即使主時鐘發生故障它仍有效。
適合應用于需要看門狗作為一個在主程序之外能夠完全獨立工作,并且對時間精度要求低的場合。
窗口看門狗(WWDG):
由從APB1時鐘分頻后得到的時鐘驅動。通過可配置的時間窗口來檢測應用程序非正常的過遲或過早操作。
適合那些要求看門狗在精確計時窗口起作用的程序。
三、獨立看門狗
1、IWDG主要性能
● 自由運行的遞減計數器
● 時鐘由獨立的RC振蕩器提供(可在停止和待機模式下工作)
● 看門狗被激活后,則在計數器計數至0x000時產生復位
2、IWDG功能描述
在鍵寄存器(IWDG_KR)中寫入0xCCCC,開始啟用獨立看門狗;此時計數器開始從其復位值0xFFF遞減計數。當計數器計數到末尾0x000時,會產生一個復位信號(IWDG_RESET)。
無論何時,只要在鍵寄存器IWDG_KR中寫入0xAAAA(喂狗), IWDG_RLR中的值就會被重新加載到計數器,從而避免產生看門狗復位 。
3、IWDG寄存器描述
需要注意:
IWDG_PR 和 IWDG_RLR 寄存器具有寫保護功能。要修改這兩個寄存器的值,必須先向IWDG_KR 寄存器中寫入 0x5555。 將其他值寫入這個寄存器將會打亂操作順序,寄存器將重新被保護。重裝載操作(即寫入 0xAAAA)也會啟動寫保護功能。
鍵寄存器(IWDG_KR)
預分頻寄存器(IWDG_PR)
重裝載寄存器(IWDG_RLR)
狀態寄存器(IWDG_SR)
4、獨立看門狗超時時間
注: 這些時間是按照40kHz時鐘給出。實際上, MCU內部的RC頻率會在30kHz到60kHz之間變化。此外,即使RC振蕩器的頻率是精確的,確切的時序仍然依賴于APB接口時鐘與RC振蕩器時鐘之間的相位差,因此總會有一個完整的RC周期是不確定的。
超出(溢出)時間計算:
Tout=((4×2^PR) ×RLR)/40
其中:Tout的單位為毫秒。
時鐘頻率LSI=40K, 一個看門狗時鐘周期就是最短超時時間。最長超時時間= (IWDG_RLR寄存器最大值)X看門狗時鐘周期。
5、IWDG獨立看門狗操作庫函數
void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess);//取消寫保護:0x5555使能
void IWDG_SetPrescaler(uint8_t IWDG_Prescaler);//設置預分頻系數:寫PR
void IWDG_SetReload(uint16_t Reload);//設置重裝載值:寫RLR
void IWDG_ReloadCounter(void);//喂狗:寫0xAAAA到KR
void IWDG_Enable(void);//使能看門狗:寫0xCCCC到KR
FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG);//狀態:重裝載/預分頻 更新
6、獨立看門狗操作步驟
代碼實現:
void BSP_WDTDOG_Init(void)
{
/ * IWDG超時等于280 ms(超時可能因LSI頻率分散而變化)* /
/ *啟用對IWDG_PR和IWDG_RLR寄存器的寫訪問* /
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
/ * IWDG計數器時鐘:40KHz(LSI)256/40每記一次數時間為:6.4ms * /
IWDG_SetPrescaler(IWDG_Prescaler_256);
/ *將計數器重載值設置為349 總計時間間距為:6.4ms * 1875 = OS_SYSWDG_TIMES * /
IWDG_SetReload((u16)(SYSWDG_TIMEOUT * 1000 /6.4 + 0.5));
/*使能看門狗*/
IWDG_Enable();
/ *重新加載IWDG計數器* /
IWDG_ReloadCounter();
}
① 取消寄存器寫保護:
IWDG_WriteAccessCmd();
例子:
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
取消IWDG_PR和IWDG_RLR寄存器具有寫保護功能(0x5555使能)
其中:
#define IWDG_WriteAccess_Enable ((uint16_t)0x5555)
#define IWDG_WriteAccess_Disable ((uint16_t)0x0000)
② 設置獨立看門狗的預分頻系數,確定時鐘:
IWDG_SetPrescaler();
例子:
IWDG_SetPrescaler(IWDG_Prescaler_256);
IWDG計數器時鐘:40KHz(LSI)256/40每記一次數時間為:6.4ms
#define IWDG_Prescaler_4 ((uint8_t)0x00)
#define IWDG_Prescaler_8 ((uint8_t)0x01)
#define IWDG_Prescaler_16 ((uint8_t)0x02)
#define IWDG_Prescaler_32 ((uint8_t)0x03)
#define IWDG_Prescaler_64 ((uint8_t)0x04)
#define IWDG_Prescaler_128 ((uint8_t)0x05)
#define IWDG_Prescaler_256 ((uint8_t)0x06)
③ 設置看門狗重裝載值,確定溢出時間:
IWDG_SetReload();
超出(溢出)時間計算:
Tout=((4×2^PR) ×RLR)/40
其中:Tout的單位為毫秒。
分頻因子=4*2^prer. 最大值只能是256
其中 Tout 為看門狗溢出時間(單位為 ms); prer 為看門狗時鐘預分頻值(IWDG_PR 值),范圍為 0~7; rlr 為看門狗的重裝載值(IWDG_RLR 的值);比如我們設定 prer 值為 4, rlr 值為 625,那么就可以得到 Tout=64×625/40=1000ms,這樣,看門狗的溢出時間就是 1s, 只要你在一秒鐘之內,有一次寫入 0XAAAA 到 IWDG_KR,就不會導致看門狗復位(當然寫入多次也是可以的)。
例子:
IWDG_SetReload((u16)(SYSWDG_TIMEOUT * 1000 /6.4 + 0.5));
我要設置12s超時,分頻因子為256.
12000= (256)XPLR/40
因此,rlr 看門狗的重裝載值為 1875.
④ 使能看門狗
IWDG_Enable();
#define KR_KEY_RELOAD ((uint16_t)0xAAAA)
#define KR_KEY_ENABLE ((uint16_t)0xCCCC)
void IWDG_Enable(void)
{
IWDG->KR = KR_KEY_ENABLE;
}
使能看門狗(寫0xCCCC到KR),啟動看門狗工作。
注意:
IWDG 在一旦啟用,就不能再被關閉!想要關閉,只能重啟,并且重啟之后不能打開 IWDG,否則問題依舊
⑤ 應用程序喂狗:
IWDG_ReloadCounter();
將使 STM32 重新加載 IWDG_RLR 的值到看門狗計數器里面。 即實現獨立看門狗的喂狗操作。
四、窗口看門狗
1、WWDG簡介
窗口看門狗通常被用來監測,**由外部干擾或不可預見的邏輯條件造成的應用程序背離正常的運行序列而產生的軟件故障。**除非遞減計數器的值在T6位變成0前被刷新,看門狗電路在達到預置的時間周期時,會產生一個MCU復位。在遞減計數器達到窗口寄存器數值之前,如果7位的遞減計數器數值(在控制寄存器中)被刷新, 那么也將產生一個MCU復位。這表明遞減計數器需要在一個有限的時間窗口中被刷新。
2、WWDG主要特性
● 可編程的自由運行遞減計數器
● 條件復位
─ 當遞減計數器的值小于0x40, (若看門狗被啟動)則產生復位。
─ 當遞減計數器在窗口外被重新裝載, (若看門狗被啟動)則產生復位。見0。
● 如果啟動了看門狗并且允許中斷,當遞減計數器等于0x40時產生早期喚醒中斷(EWI),它可以被用于重裝載計數器以避免WWDG復位。
3、WWDG功能描述
如果看門狗被啟動(WWDG_CR寄存器中的WDGA位被置’1’), 并且當7位(T[6:0])遞減計數器從0x40翻轉到0x3F(T6位清零)時,則產生一個復位**。如果軟件在計數器值大于窗口寄存器中的數值時重新裝載計數器,將產生一個復位。**
應用程序在正常運行過程中必須定期地寫入WWDG_CR寄存器以防止MCU發生復位。只有當計數器值小于窗口寄存器的值時,才能進行寫操作。儲存在WWDG_CR寄存器中的數值必須在0xFF和0xC0之間:
● 啟動看門狗
在系統復位后,看門狗總是處于關閉狀態,設置WWDG_CR寄存器的WDGA位能夠開啟看門狗,隨后它不能再被關閉,除非發生復位。
● 控制遞減計數器
遞減計數器處于自由運行狀態,即使看門狗被禁止,遞減計數器仍繼續遞減計數。當看門狗被啟用時, T6位必須被設置,以防止立即產生一個復位。
T[5:0]位包含了看門狗產生復位之前的計時數目;復位前的延時時間在一個最小值和一個最大值之間變化,這是因為寫入WWDG_CR寄存器時,預分頻值是未知的。
配置寄存器(WWDG_CFR) 中包含窗口的上限值:要避免產生復位,遞減計數器必須在其值小于窗口寄存器的數值并且大于0x3F時被重新裝載, 0描述了窗口寄存器的工作過程。
另一個重裝載計數器的方法是利用早期喚醒中斷(EWI)。設置WWDG_CFR寄存器中的WEI位開啟該中斷。當遞減計數器到達0x40時,則產生此中斷,相應的中斷服務程序(ISR)可以用來加載計數器以防止WWDG復位。在WWDG_SR寄存器中寫’0’可以清除該中斷。
注: 可以用T6位產生一個軟件復位(設置WDGA位為’1’, T6位為’0’)。
4、如何編寫看門狗超時程序
除非遞減計數器的值在 T6 位(WWDG->CR 的第六位)變成 0 前被刷新,看門狗電路在達到預置的時間周期時,會產生一個 MCU 復位。在遞減計數器達到窗口配置寄存器(WWDG->CFR)數值之前,如果 7 位的遞減計數器數值(在控制寄存器中)被刷新, 那么也將產生一個 MCU 復位。這表明遞減計數器需要在一個有限的時間窗口中被刷新。
T[6:0]就是 WWDG_CR 的低七位, W[6:0]即是 WWDG->CFR 的低七位。
T[6:0]就是窗口看門狗的計數器,而 W[6:0]則是窗口看門狗的上窗口,下窗口值是固定的(0X40)。
當窗口看門狗的計數器在上窗口值之外被刷新,或者低于下窗口值都會產生復位。
上窗口值(W[6:0]) 是由用戶自己設定的,根據實際要求來設計窗口值,但是一定要確保窗口值大于 0X40,否則窗口就不存在了。
窗口看門狗的超時公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;
其中:
Twwdg: WWDG 超時時間(單位為 ms)
Fpclk1: APB1 的時鐘頻率(單位為 Khz)
WDGTB: WWDG 的預分頻系數
T[5:0]:窗口看門狗的計數器低 6 位
根據上面的公式,假設 Fpclk1=36Mhz,那么可以得到最小-最大超時時間表如下表所示:
5、寄存器描述
控制寄存器(WWDG_CR)
WWDG_CR 只有低八位有效, T[6: 0]用來存儲看門狗的計數器值,
隨時更新的,每個窗口看門狗計數周期(4096×2^ WDGTB)減 1。當該計數器的值從 0X40 變為 0X3F 的時候,將產生看門狗復位。
WDGA 位則是看門狗的激活位,該位由軟件置 1,以啟動看門狗,并且一定要注意的是該位一旦設置,就只能在硬件復位后才能清零了。
配置寄存器(WWDG_CFR)
該位中的 EWI 是提前喚醒中斷,也就是在快要產生復位的前一段時間(T[6:0]=0X40) 來提醒我們,需要進行喂狗了,否則將復位!因此,我們一般用該位來設置中斷,當窗口看門狗的計數器值減到 0X40 的時候,如果該位設置,并開啟了中斷,則會產生中斷,我們可以在中斷里面向 WWDG_CR 重新寫入計數器的值,來達到喂狗的目的。注意這里在進入中斷后, 必須在不大于 1 個窗口看門狗計數周期的時間(在 PCLK1 頻率為 36M 且 WDGTB 為 0 的條件下,該時間為 113us)內重新寫 WWDG_CR,否則,看門狗將產生復位!
狀態寄存器(WWDG_SR)
該寄存器用來記錄當前是否有提前喚醒的標志。該寄存器僅有位 0 有效,其他都是保留位。當計數器值達到 40h 時,此位由硬件置 1。
它必須通過軟件寫 0 來清除。對此位寫 1 無效。 即使中斷未被使能, 在計數器的值達到 0X40的時候, 此位也會被置 1。
6、窗口看門狗操作步驟
代碼示例:
//保存 WWDG 計數器的設置值,默認為最大.
u8 WWDG_CNT=0x7f;
//初始化窗口看門狗
//tr :T[6:0],計數器值
//wr :W[6:0],窗口值
//fprer:分頻系數(WDGTB) ,僅最低 2 位有效
//Fwwdg=PCLK1/(4096*2^fprer).
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 時鐘使能
WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.
WWDG_SetPrescaler(fprer); //設置 IWDG 預分頻值
WWDG_SetWindowValue(wr); //設置窗口值
WWDG_Enable(WWDG_CNT); //使能看門狗,設置 counter
WWDG_ClearFlag(); //清除提前喚醒中斷標志位
WWDG_NVIC_Init(); //初始化窗口看門狗 NVIC
WWDG_EnableIT(); //開啟窗口看門狗中斷
}
//重設置 WWDG 計數器的值
void WWDG_Set_Counter(u8 cnt)
{
WWDG_Enable(cnt); //使能看門狗,設置 counter .
}
//窗口看門狗中斷服務程序
void WWDG_NVIC_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; //WWDG 中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //搶占 2 子優先級 3 組 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //搶占 2,子優先級 3,組 2
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure); //NVIC 初始化
}
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(WWDG_CNT); //當禁掉此句后,窗口看門狗將產生復位
WWDG_ClearFlag(); //清除提前喚醒中斷標志位
LED1=!LED1; //LED 狀態翻轉
}
① 使能 WWDG 時鐘
WWDG 不同于 IWDG, IWDG 有自己獨立的 40Khz 時鐘,不存在使能問題。而 WWDG使用的是 PCLK1 的時鐘,需要先使能時鐘。 方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG 時鐘使能
② 設置窗口值和分頻數
設置窗口值的函數是:
void WWDG_SetWindowValue(uint8_t WindowValue);
這個函數的入口參數 WindowValue 用來設置看門狗的上窗口值。設置分頻數的函數是:
void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);
這個函數同樣只有一個入口參數,用來設置看門狗的分頻值。
③ 開啟 WWDG 中斷并分組
開啟 WWDG 中斷的函數為:
WWDG_EnableIT(); //開啟窗口看門狗中斷
接下來是進行中斷優先級配置,這里就不重復了,使用 NVIC_Init()函數即可。
④ 設置計數器初始值并使能看門狗
這一步在庫函數里面是通過一個函數實現的:
void WWDG_Enable(uint8_t Counter);
該函數既設置了計數器初始值,同時使能了窗口看門狗。
五、總結
看門狗,這個因為工程里用的是獨立看門狗,所以對它了解比較多一些。
窗口看門狗,我是真心的沒有看一下去。。。 復制粘貼了一通,也沒太搞明白。
上一篇:STM32開發 -- YModem詳解
下一篇:STM32開發 -- UTC、UNIX時間戳、北京時間之間的轉換
推薦閱讀
史海拾趣
面對日益嚴峻的環境問題和可持續發展的挑戰,BERGQUIST公司始終堅持綠色發展的理念。公司不斷投入研發力量,開發環保型熱管理材料和生產工藝。同時,公司還積極推廣節能減排技術,努力降低生產過程中的能耗和排放。這些舉措不僅符合社會發展趨勢,也為公司的可持續發展提供了有力保障。
這五個故事從不同角度展示了BERGQUIST公司在電子行業中的發展歷程和成就,體現了公司不斷創新、追求卓越的精神。這些事實性的描述旨在客觀呈現BERGQUIST公司的歷史與現狀,不含任何褒貶之意。
在快速發展的過程中,BNS Solutions公司始終注重品質管理和品牌建設。公司建立了一套完善的質量管理體系,從原材料采購到產品生產、銷售等各個環節都嚴格把控質量。同時,公司還注重品牌形象的塑造和維護,通過廣告宣傳、公關活動等方式不斷提升品牌知名度和美譽度。這些舉措使得BNS Solutions公司的產品在市場上具有更高的競爭力,贏得了消費者的信賴和喜愛。
隨著全球環境問題的日益嚴重,環保和可持續發展已經成為電子行業的重要議題。CYMBET公司積極響應這一趨勢,致力于環保和可持續發展。公司的EnerChip電池芯片采用環保材料制造,具有生物相容性,不會對環境造成污染。此外,CYMBET還積極探索綠色生產技術和資源循環利用方案,減少生產過程中的能源消耗和廢棄物排放。這種對環保和可持續發展的重視不僅體現了CYMBET的社會責任感,也為公司的可持續發展奠定了堅實的基礎。
在電子行業中,技術的更新換代速度極快。為了保持競爭力,CYMBET公司始終將創新作為核心驅動力。公司不斷投入研發資金,引進先進設備和技術人才,對EnerChip技術進行持續的優化和升級。例如,公司成功研發出了更高能量密度、更長壽命的EnerChip電池芯片,進一步提升了產品的性能和市場競爭力。同時,CYMBET還積極探索新的應用領域,將EnerChip技術應用于可穿戴設備、物聯網等新興領域,為公司帶來了新的增長點。
1994年,Alpha Semiconductor迎來了另一個重要的里程碑——公司成功研發出了自己的電源管理產品。這一產品的推出標志著Alpha Semiconductor在半導體技術領域的自主創新能力得到了顯著提升。電源管理產品的成功研發不僅為公司帶來了可觀的收益,也進一步鞏固了Alpha Semiconductor在半導體行業中的地位。
附件里也有硬件連接圖!!!我用的附件文件夾(解壓縮后得)內的單片機程序(ASM格式,用的keil軟件編譯,后用燒錄器直接燒進單片機內實驗),原希望當單片機收到一個數0CH時。可以每隔一秒發一個數(從0FFH到01H)給PC機。 出現的問題:收是收到了 ...… 查看全部問答∨ |
嗯,先弄個非常標題黨的Title——C語言降龍十八掌。 大家有空的一起來討論討論,思想的碰撞才能放出火花。 第一掌—— main函數不簡單 http://bbs.eeworld.com.cn/thread-87910-1-1.html… 查看全部問答∨ |
本文轉引自 飛凌嵌入式 www.witech.com.cn 很多初學51單片機的網友會有這樣的問題:AT89S51是什么 書上和網絡教程上可都是8051,89C51等!沒聽說過有89S51 ! 這里,初學者要澄清單片機實際使用方面的一個產品概念,MCS-51單片機是美國INTE公司于1980年 ...… 查看全部問答∨ |
|
很高興能獲得提名;TI的推廣還是很給力的,贊一下,想當初本科時候的同學都能申請到dsp芯片;希望大家多提寶貴意見,我表示感謝:carnation:… 查看全部問答∨ |