前幾天學習STM32的兩條狗,先學習了寵物狗(IWDG),和其它MCU差不多,不多說了。學到警犬(WWDG)的時候,問題來了,沒有IWDG那么好理解了,看了半天沒有搞懂是怎么回事,計數器值、窗口值、在什么時候喂狗、什么時候產生中斷等等,一頭霧水。
經過兩天的推敲,個人理解如下:
本文引用地址:http://www.104case.com/article/201611/321561.htm1、有個7位遞減計數器(WWDG->CR),就這個計數器和窗口計數器(WWDG->CFR)決定什么時候喂狗。
狗喂早了,復位——“早”體現在計數器值(tr)>窗口值(wr),也就是計數器值還沒有減到窗口值以下;
2、當 0x40 < 計數器值(tr) < 窗口值(wr) 時,這時候最適合喂狗了,也只有在這時候喂狗才合適;
3、當計數器的值從0x40變到0x3F的時候,將產生看門狗復位;當然在要產生復位的前一段時間,如果開啟了提前喚醒中斷,那么就會進入中斷,在中斷函數里,我們需要及時喂狗,否則會產生復位;
4、據網上資料介紹,在這個中斷里面一般不進行喂狗,一般是系統去世前的“遺囑”,比如存儲重要的數據等。這個就需要根據個人需要設計。
下面擇取部分程序,可以根據程序說明,計算出喂狗的時間,大家注意推敲,歡迎交流!
u8 WWDG_CNT = 0x7F;
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(); // 開啟窗口看門狗中斷
}
void WWDG_IRQHandler(void)
{
WWDG_ClearFlag(); // 清除提前喚醒中斷標志位
LED1 = !LED1; // LED1 狀態翻轉
printf("進入中斷!rn");
}
int main(void)
{
u8 tr, wr;
delay_init();
NVIC_Configuration(); // 設置NVIC中斷分組2:2位搶占優先級, 2位響應優先級
LED_Init();
KEY_Init();
uart_init(9600);
LED0 = 0;
delay_ms(300);
WWDG_Init(0x7F, 0x5F, WWDG_Prescaler_8); // 計數器值為7f, 窗口寄存器值為5f, 分頻數為8
while(1)
{
LED0 = 1;
wr=WWDG->CFR&0X7F; // 窗口值
tr=WWDG->CR&0X7F; // 計數器值
if(tr // 計數器值tr必須小于窗口值wr時才能喂狗,在之前喂狗則太早,會產生看門狗復位
{
WWDG_SetCounter(WWDG_CNT);
printf("正在喂狗!rn");
}
}
}
實踐出真知!
試驗現象:DS0(紅燈)先亮,再滅,DS1無變化。
試驗現象說明:在規定的時間段及時的喂狗了,程序沒有進入中斷函數。
評論