天天看點

看門狗喂狗被狗咬——視窗看門狗

喂狗:重新把裝載寄存器中的值裝載至計數寄存器或者直接往計數寄存器寫入資料,保證mcu不會複位。

被狗咬:沒有及時喂狗或者喂狗過于頻繁,後者隻存在于視窗看門狗,在獨立看門狗中不存在喂狗過快還被狗咬的現象。

也不知道誰起的名字。。。。。。

視窗看門狗之是以叫視窗就是因為其喂狗時間是一個有上下限的範圍(視窗)。通過設定相關寄存器,設定其上限時間(下限固定),喂狗的時間不能過早也不能過晚。

獨立看門狗限制喂狗時間在0-x内,x由相關寄存器決定。喂狗的時間不能過晚。

看門狗喂狗被狗咬——視窗看門狗

結合圖示說明視窗看門狗的工作流程:

視窗看門狗開啟之後,cnt遞減計數器開始工作,初始值人為決定,但是一定要大于3FH,stm32f10x系列計數寄存器WWDG_CR隻有低8位有效,其中低7位即

T[0:6]儲存計數值,最高為7FH,當其遞減至3FH時候,表示到到了視窗的下限,在這之前如果沒有喂狗就要被狗咬了。

除了計數寄存器之外還有一個重要寄存器來設定視窗的上限,stm32f10x系列的配置寄存器WWDG_CFR低10位有效,但是低7位即W[6:0]來儲存上限數值。視窗上限可以自己設定,但是一定不能低于3FH,如果低于了就不會有視窗。

是以,視窗看門狗隻能在圖示重新整理視窗内喂狗,高于上限或者低于下限都會被狗咬。

看門狗喂狗被狗咬——視窗看門狗

視窗看門狗邏輯圖如上,結合圖再來說明被狗咬的兩種情況。

CFR即上文說的配置寄存器,低7位設定視窗上限(W6:0簡稱W6),CR即上文說的計數寄存器,低7位儲存計數數值(T6:0簡稱T6),第8位是啟動位,啟動之後WDGA一直是1。

當T6>W6時,即計數還沒有到達3FH,如果此時喂狗即圖中寫入WWDG_CR,與運算得到1,經過或運算仍然為1,最後導緻mcu複位。

當T6從7FH減小至3FH時,CR寄存器第6位由1變為0,取反或運算得到1,最終使得mcu複位。

視窗看門狗實作流程:

(1)使能看門狗時鐘

(2)設定分頻系數

(3)設定上視窗值

(4)開啟提前喚醒中斷并分組

(5)使能看門狗

(6)喂狗

(7)編寫中斷服務函數

在stm32f103zet6中實作視窗看門狗代碼如下:

u8 WWDG_CNT=0x7f;  //儲存WWDG計數器的設定值,預設為最大. 
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);設定WWDG預分頻值
 WWDG_SetWindowValue(wr);//設定視窗值
 WWDG_Enable(WWDG_CNT);  //使能看門狗 , 設定 counter .                  
 WWDG_ClearFlag();//清除提前喚醒中斷标志位 
 WWDG_NVIC_Init();//初始化視窗看門狗 NVIC
 WWDG_EnableIT(); //開啟視窗看門狗中斷
} 
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_Enable(WWDG_CNT);   //(當禁掉此句後,視窗看門狗将産生複位)使能看門狗,設定WWDG計數器的值
 WWDG_ClearFlag();   //清除提前喚醒中斷标志位
 LED1=!LED1;   //LED狀态翻轉
}
           

主函數如下:

int main(void)
 {  
 delay_init();       //延時函數初始化   
 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定中斷優先級分組為組2:2位搶占優先級,2位響應優先級
LED_Init();
LED0=0;
delay_ms(300);   
WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//計數器值為7f,視窗寄存器為5f,分頻數為8    
  while(1)
 {
  LED0=1;         
 }   
}
           

繼續閱讀