stm32 窗口看门狗学习(一)
什么是窗口看門狗?
1)獨立看門狗 ?
? ? ? ? ? ? ?限制喂狗時間在0-x內,x由相關寄存器決定。喂狗的時間不能過晚。
2)窗口看門狗?
? ? ? ? ? ? ?之所以稱為窗口就是因為其喂狗時間是一個“窗口”,不能過早也不能過晚。
STM32F10x 的窗口看門狗中有一個7位的遞減計數器,出現下述2種情況之一時產生看門狗復位:
1)當計數器的數值從0x40減到0x3F時 ,這里的0x3F可以看成是窗口的下限;
2)喂狗的時候,如果計數器的值大于某一設定數值(這個數值是窗口的上限),此數值在WWDG_CFR寄存器中配置。
對于一般的看門狗,程序可以在它產生復位前的任意時刻刷新看門狗。但這有一個隱患,有可能程序跑亂了又跑回到正常的地方,或者說跑亂的程序正好執行了刷新看門狗操作,這樣的情況一般的看門狗不好檢測;??
如果使用窗口看門狗,程序員可以根據程序正常執行的時間設置一個時間窗口,保證不會提前刷新看門狗也不會滯后刷新看門狗,這樣可以檢測出程序沒有按照正常的路徑運行的情況。
如果非要說窗口看門狗的具體應用,我一時也說不上來,因為沒有用過。但是這不妨礙我們做實驗學習窗口看門狗。
先看一幅圖,直觀地認識窗口看門狗。
T[6:0]是一個7位的遞減計數器,我們刷新看門狗,就是重載這個計數器;W[6:0]是提前配置好的一個數值,作為窗口的上限;0x3F是窗口的下限,是固定值,程序無法修改。
假如設置T[6:0]的重載值是0x7F, ?W[6:0]為0x5F, ?那么計數器從0x7F遞減到0x5F的過程中(也就是T[6:0]大于W[6:0]的時候),是不能喂狗的。如果喂狗就會復位。
當T[6:0]從W[6:0]遞減到0x3F的過程中,需要喂狗,不然計數器等于0x3F的時候就會復位。
時間怎么計算?
根據手冊,計數器的計數周期 = T_PCLK1 * 2^WDGTB * 4096,
這里WDGTB是預分頻系數,取值范圍是(0,1,2,3)
假設我們實驗中PCLK1的頻率是36MHz,WDGTB取3,那么計數器的計數周期?
T = (1/(36M))* 8 * 4096(s)= 910.222 us
我們設計一下實驗一。
1.實驗中PCLK1的頻率是36MHz,WDGTB取3;
2.T[6:0]設置為0x7F,W[6:0]設置為0x41; 那么刷新窗口就是(0x41~0x3F), 在(0x7F~0x41)是不允許刷新的;
不允許刷新的時間 =?(0x7F - 0x41) * 910.222 us = 56.43 ms
3.我們在在(0x7F~0x41)這段時間刷新,看看是不是復位(預期結果是一定復位)。
<span style="font-size:18px;"><span style="font-size:18px;">//初始化窗口看門狗 //tr :T[6:0],計數器初始值 //wr :W[6:0],窗口上限 //fprer:預分頻系數,WDGTB[1:0] //計數器的計數頻率 F_wwdg = PCLK1/(4096*2^fprer). void WWDG_Init(u8 tr,u8 wr,u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG時鐘使能WWDG_SetPrescaler(fprer);//設置預分頻系數WWDG_SetWindowValue(wr);//設置窗口上限WWDG_Enable(tr); //設置計數器初值并且使能看門狗 } </span></span>喂狗的函數是: <span style="font-size:18px;"><span style="font-size:18px;">void WWDG_SetCounter(uint8_t Counter)</span></span>
看看main函數。
<span style="font-size:18px;">int main(void) { delay_init(); uart_init(9600); LED_Init();printf("Hello World ! \r\n");delay_ms(970);WWDG_Init(0x7F,0x41,3);//窗口看門狗初始化delay_ms(30); //必須小于56.43msWWDG_SetCounter(0x7F); //喂狗,應該產生復位while(1){LED0 = !LED0;delay_ms(300); }}</span>看看實驗結果。
確實1s左右會重啟一次。
如果我們不喂狗,把那行語句注釋調
<span style="font-size:18px;">//WWDG_SetCounter(0x7F); //喂狗,應該產生復位</span>結果是也會復位,但是LED沒有閃爍,為什么呢?估計是還沒有執行到操作LED的語句的時候就復位了。 <span style="font-size:18px;">//delay_ms(30); </span> 把這句也注釋了,就可以看到燈的閃爍。
實驗二
1.實驗中PCLK1的頻率是36MHz,WDGTB取3;
2.T[6:0]設置為0x7F,W[6:0]設置為0x7E; 那么刷新窗口就是(0x7E~0x3F), 在(0x7F~0x7E)是不允許刷新的;
不允許刷新的時間 =?(0x7F - 0x7E) * 910.222 us = 0.91 ms
3.我們在在(0x7E~0x3F),這段時間刷新,看看是不是復位(預期結果是不復位)。
<span style="font-size:18px;">int main(void) { delay_init(); uart_init(9600); LED_Init();delay_ms(200);LED0=0; //led onprintf("Hello World ! \r\n");delay_ms(200);LED0= 1; //led offWWDG_Init(0x7F,0x7E,3); while(1){delay_ms(1); WWDG_SetCounter(0x7F); //喂狗}} </span> 實驗結果是不復位,燈不閃爍,串口也不打印。如果把喂狗的語句注釋調,就會看到燈一直在閃爍,串口一直打印,說明一直復位。
上面的代碼,喂狗的時間不好掌握,很容易錯過窗口。參考網上的例子,有一種查詢的方法喂狗。
while(1){if((WWDG->CR & 0x7F) == 0x55)WWDG_SetCounter(0x7F); }
今天就說到這里,下次接著玩。
總結
以上是生活随笔為你收集整理的stm32 窗口看门狗学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国汽车产业数字化服务商研究报告及TOP
- 下一篇: stm32 窗口看门狗学习(二)