窗口看門(mén)狗(WWDG)概述
窗口看門(mén)狗通常被用來(lái)監(jiān)測(cè),由外部干擾或不可預(yù)見(jiàn)的邏輯條件造成的應(yīng)用程序背離正常的運(yùn)行序列而產(chǎn)生的軟件故障。除非遞減計(jì)數(shù)器的值在T6位變成0前被刷新,否則看門(mén)狗電路在達(dá)到預(yù)置的時(shí)間周期時(shí),會(huì)產(chǎn)生一個(gè)MCU復(fù)位。
在遞減計(jì)數(shù)器達(dá)到窗口寄存器數(shù)值之前,如果7位的遞減計(jì)數(shù)器數(shù)值(在控制寄存器中)被刷新, 那么也將產(chǎn)生一個(gè)MCU復(fù)位。這表明遞減計(jì)數(shù)器需要在一個(gè)有限的時(shí)間窗口中被刷新。
WWDG主要特性
● 可編程的自由運(yùn)行遞減計(jì)數(shù)器
● 條件復(fù)位 ─ 當(dāng)遞減計(jì)數(shù)器的值小于0x40,(若看門(mén)狗被啟動(dòng))則產(chǎn)生復(fù)位。
─ 當(dāng)遞減計(jì)數(shù)器在窗口外被重新裝載,(若看門(mén)狗被啟動(dòng))則產(chǎn)生復(fù)位。
● 如果啟動(dòng)了看門(mén)狗并且允許中斷,當(dāng)遞減計(jì)數(shù)器等于0x40時(shí)產(chǎn)生早期喚醒中斷(EWI),它可以被用于重裝載計(jì)數(shù)器以避免WWDG復(fù)位。
WWDG功能描述
如果看門(mén)狗被啟動(dòng)(WWDG_CR寄存器中的WDGA位被置’1’), 并且當(dāng)7位(T[6:0])遞減計(jì)數(shù)器從0x40翻轉(zhuǎn)到0x3F(T6位清零)時(shí),則產(chǎn)生一個(gè)復(fù)位。
如果軟件在計(jì)數(shù)器值大于窗口寄存器中的數(shù)值時(shí)重新裝載計(jì)數(shù)器,將產(chǎn)生一個(gè)復(fù)位。
應(yīng)用程序在正常運(yùn)行過(guò)程中必須定期地寫(xiě)入WWDG_CR寄存器以防止MCU發(fā)生復(fù)位。只有當(dāng)計(jì)數(shù)器值小于窗口寄存器的值時(shí),才能進(jìn)行寫(xiě)操作。儲(chǔ)存在WWDG_CR寄存器中的數(shù)值必須在0xFF和0xC0之間:
● 啟動(dòng)看門(mén)狗
在系統(tǒng)復(fù)位后,看門(mén)狗總是處于關(guān)閉狀態(tài),設(shè)置WWDG_CR寄存器的WDGA位能夠開(kāi)啟看門(mén)狗,隨后它不能再被關(guān)閉,除非發(fā)生復(fù)位。
● 控制遞減計(jì)數(shù)器
遞減計(jì)數(shù)器處于自由運(yùn)行狀態(tài),即使看門(mén)狗被禁止,遞減計(jì)數(shù)器仍繼續(xù)遞減計(jì)數(shù)。當(dāng)看門(mén)狗被啟用時(shí),T6位必須被設(shè)置,以防止立即產(chǎn)生一個(gè)復(fù)位。
T[5:0]位包含了看門(mén)狗產(chǎn)生復(fù)位之前的計(jì)時(shí)數(shù)目;復(fù)位前的延時(shí)時(shí)間在一個(gè)最小值和一個(gè)最大值之間變化,這是因?yàn)閷?xiě)入WWDG_CR寄存器時(shí),預(yù)分頻值是未知的。
配置寄存器(WWDG_CFR) 中包含窗口的上限值:要避免產(chǎn)生復(fù)位,遞減計(jì)數(shù)器必須在其值小于窗口寄存器的數(shù)值并且大于0x3F時(shí)被重新裝載。
另一個(gè)重裝載計(jì)數(shù)器的方法是利用早期喚醒中斷(EWI)。設(shè)置WWDG_CFR寄存器中的WEI位開(kāi)啟該中斷。當(dāng)遞減計(jì)數(shù)器到達(dá)0x40時(shí),則產(chǎn)生此中斷,相應(yīng)的中斷服務(wù)程序(ISR)可以用來(lái)加載計(jì)數(shù)器以防止WWDG復(fù)位。在WWDG_SR寄存器中寫(xiě)’0’可以清除該中斷。
注: 可以用T6位產(chǎn)生一個(gè)軟件復(fù)位(設(shè)置WDGA位為’1’,T6位為’0’)。
T[6:0]就是 WWDG_CR 的低七位,W[6:0]即是 WWDG->CFR 的低七位。T[6:0] 就是窗口看門(mén)狗的計(jì)數(shù)器,而 W[6:0]則是窗口看門(mén)狗的上窗口,下窗口值是固定的(0X40)。 當(dāng)窗口看門(mén)狗的計(jì)數(shù)器在上窗口值之外被刷新,或者低于下窗口值都會(huì)產(chǎn)生復(fù)位。
上窗口值(W[6:0])是由用戶自己設(shè)定的,根據(jù)實(shí)際要求來(lái)設(shè)計(jì)窗口值,但是一定要確保 窗口值大于 0X40,否則窗口就不存在了。 窗口看門(mén)狗的超時(shí)公式如下:
Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1;
其中:
Twwdg:WWDG 超時(shí)時(shí)間(單位為 ms)
Fpclk1:APB1 的時(shí)鐘頻率(單位為 Khz)
WDGTB:WWDG 的預(yù)分頻系數(shù)
T[5:0]:窗口看門(mén)狗的計(jì)數(shù)器低 6 位
根據(jù)上面的公式,假設(shè) Fpclk1=36Mhz,那么可以得到最小-最大超時(shí)時(shí)間如下表
調(diào)試模式
當(dāng)微控制器進(jìn)入調(diào)試模式時(shí)(Cortex-M3核心停止),根據(jù)調(diào)試模塊中的DBG_WWDG_STOP 配置位的狀態(tài),WWDG的計(jì)數(shù)器能夠繼續(xù)工作或停止。
窗口看門(mén)狗(WWDG)寄存器
控制寄存器(WWDG_CR)
WWDG_CR 只有低八位有效,T[6:0]用來(lái)存儲(chǔ)看門(mén)狗的計(jì)數(shù)器值, 隨時(shí)更新的,每個(gè)窗口看門(mén)狗計(jì)數(shù)周期(4096×2^ WDGTB)減 1。當(dāng)該計(jì)數(shù)器的值從 0X40 變 為 0X3F 的時(shí)候,將產(chǎn)生看門(mén)狗復(fù)位。
WDGA 位則是看門(mén)狗的激活位,該位由軟件置 1,以啟動(dòng)看門(mén)狗,并且一定要注意的是該 位一旦設(shè)置,就只能在硬件復(fù)位后才能清零了。
配置寄存器(WWDG_CFR)
該位中的 EWI位是提前喚醒中斷位,也就是在快要產(chǎn)生復(fù)位的前一段時(shí)間(T[6:0]=0X40)來(lái)提醒我們,需要進(jìn)行喂狗了,否則將復(fù)位!
因此,我們一般用該位來(lái)設(shè)置中斷,當(dāng)窗口看門(mén)狗的計(jì)數(shù)器值減到 0X40 的時(shí)候,如果該位設(shè)置,并開(kāi)啟了中斷,則會(huì)產(chǎn)生中斷,我們可以在中斷里面向 WWDG_CR 重新寫(xiě)入計(jì)數(shù)器的值,來(lái)達(dá)到喂狗的目的。注意這里在進(jìn)入中斷后,必須在不大于 1 個(gè)窗口看門(mén)狗計(jì)數(shù)周期的時(shí)間(在 PCLK1 頻率為 36M 且 WDGTB 為 0 的條件下, 該時(shí)間為 113us)內(nèi)重新寫(xiě) WWDG_CR,否則,看門(mén)狗將產(chǎn)生復(fù)位!
狀態(tài)寄存器(WWDG_SR)
該寄存器用來(lái)記錄當(dāng)前是否有提前喚醒的標(biāo)志。該寄存器僅有位 0 有效,其他都是保留位。當(dāng)計(jì)數(shù)器值達(dá)到 40h 時(shí),此位由硬件置 1。 它必須通過(guò)軟件寫(xiě) 0 來(lái)清除。對(duì)此位寫(xiě) 1 無(wú)效。即使中斷未被使能,在計(jì)數(shù)器的值達(dá)到 0X40的時(shí)候,此位也會(huì)被置 1。
窗口看門(mén)狗(WWDG)寄存器映像
WWDG固件庫(kù)函數(shù)
窗口看門(mén)狗庫(kù)函數(shù)相關(guān)源碼和定義分布在文件 stm32f10x_wwdg.c 文件和頭文件 stm32f10x_wwdg.h 中。
1)使能 WWDG 時(shí)鐘
WWDG 不同于IWDG,IWDG 有自己獨(dú)立的 40Khz 時(shí)鐘,不存在使能問(wèn)題。而 WWDG使用的是 PCLK1 的時(shí)鐘,需要先使能時(shí)鐘。方法是:
2)設(shè)置窗口值和分頻數(shù)
設(shè)置窗口值的函數(shù)是:
這個(gè)函數(shù)的入口參數(shù) WindowValue 用來(lái)設(shè)置看門(mén)狗的上窗口值。
設(shè)置分頻數(shù)的函數(shù)是:
這個(gè)函數(shù)同樣只有一個(gè)入口參數(shù),用來(lái)設(shè)置看門(mén)狗的分頻值。
3)開(kāi)啟 WWDG 中斷并分組
開(kāi)啟 WWDG 中斷的函數(shù)為:
接下來(lái)是進(jìn)行中斷優(yōu)先級(jí)配置,這里就不重復(fù)了,使用 NVIC_Init()函數(shù)即可。
4)設(shè)置計(jì)數(shù)器初始值并使能看門(mén)狗
這一步在庫(kù)函數(shù)里面是通過(guò)一個(gè)函數(shù)實(shí)現(xiàn)的:
該函數(shù)既設(shè)置了計(jì)數(shù)器初始值,同時(shí)使能了窗口看門(mén)狗。
5)編寫(xiě)中斷服務(wù)函數(shù)
編寫(xiě)窗口看門(mén)狗的中斷服務(wù)函數(shù),通過(guò)該函數(shù)來(lái)喂狗,必須在不大于 1 個(gè)窗口看門(mén)狗計(jì)數(shù)周期的時(shí)間內(nèi)完成喂狗,否則當(dāng)窗口看門(mén)狗計(jì)數(shù)器值減到 0X3F 的時(shí)候,就會(huì)引起軟復(fù)位了。在中斷服務(wù)函數(shù)里面也要將狀態(tài)寄存器的 EWIF 位清空。
WWDG(窗口看門(mén)狗)實(shí)驗(yàn)
硬件設(shè)計(jì)
1) 指示燈 DS0 和 DS1
2) 窗口看門(mén)狗
窗口看門(mén)狗屬于 STM32 的內(nèi)部資源,只需要軟件設(shè)置好即可正常工作。我們通過(guò) DS0 和 DS1 來(lái)指示 STM32 的復(fù)位情況和窗口看門(mén)狗的喂狗情況。
軟件設(shè)計(jì)
在工程文件目錄下面新建兩個(gè)文件夾分別為:wdg.c和wdg.h。并在把源文件添加到工程,和添加頭文件的路徑。
wdg.c 里面的代碼如下:
?
第一個(gè)函數(shù) void WWDG_Init(u8 tr,u8 wr,u8 fprer)用來(lái)設(shè)置 WWDG 的初始化值。包括看門(mén)狗計(jì)數(shù)器的值和看門(mén)狗比較值等。全局變量 WWDG_CNT,該變量用來(lái)保 存最初設(shè)置 WWDG_CR 計(jì)數(shù)器的值。在后續(xù)的中斷服務(wù)函數(shù)里面,就又把該數(shù)值放回到WWDG_CR 上。
第二個(gè)函數(shù)WWDG_Set_Counter()是用來(lái)重設(shè)窗口看門(mén)狗的計(jì)數(shù)器值的。
第三個(gè)函數(shù)是中斷分組函數(shù)。
第四個(gè)函數(shù)是中斷服務(wù)函數(shù),先重設(shè)窗口看門(mén)狗的計(jì)數(shù)器值,然后清除提前喚醒中斷標(biāo)志。函數(shù)中也對(duì) LED1(DS1)取反,來(lái)監(jiān)測(cè)中斷服務(wù)函數(shù)的執(zhí)行了狀況。
wdg.h 里面的代碼如下:
把頭文件中的幾個(gè)函數(shù)名加入到頭文件里面去,其他文件的文件可以調(diào)用。
main.c中的代碼:
該函數(shù)通過(guò) LED0(DS0)來(lái)指示是否正在初始化。而 LED1(DS1)用來(lái)指示是否發(fā)生了中 斷。我們先讓 LED0 亮 300ms,然后關(guān)閉以用于判斷是否有復(fù)位發(fā)生了。在初始化 WWDG 之后,我們回到死循環(huán),關(guān)閉 LED1,并等待看門(mén)狗中斷的觸發(fā)/復(fù)位。
實(shí)驗(yàn)現(xiàn)象
DS0 亮一下之后熄滅,緊接著 DS1 開(kāi)始不停的閃爍。每秒鐘閃爍 5 次左右。
評(píng)論