1、WWDG簡介
窗口看門狗(WWDG)是喂狗時間有上下限范圍的看門狗,主要用于檢測由外部干擾和不可預測的邏輯條件導致程序跑飛了所引起的軟件問題,根據(jù)程序正常執(zhí)行的時間設置刷新看門狗的一個時間窗口,保證不會提前刷新看門狗或滯后刷新看門狗,可以用于檢測出程序是否按照正常的路徑運行或者是非正常的跳過某些程序段的情況。
復位
當WWDG計數(shù)器的值大于設定的上限窗口值時喂狗,將產(chǎn)生復位;當計數(shù)器的值從下限固定值0x40變成0x3F時,低于窗口看門狗的下限,也會產(chǎn)生復位。
計數(shù)器時鐘
WWDG計數(shù)器時鐘由CK計時器時鐘經(jīng)過預分頻器分頻得到,預分頻器的時基由配置寄存器(WWDG_CFGR)的WDGTB位配置,如圖1所示,CK計時器時鐘=PCLK1/4096,可將CK計時器時鐘進行2分頻/4分頻/8分頻/不分頻。
計數(shù)器
WWDG的計數(shù)器是一個遞減計數(shù)器,每4096x2WDGTB個PCLK1周期減1,WDGTB的值如圖1所示??刂萍拇嫫?WWDG_CR)的T位用于存儲看門狗的7位計數(shù)器值,如圖2所示,計數(shù)器所有位置1時為最大值0x7F,其下限固定值為0x40,當計數(shù)器值從0x40下降到0x3F時,產(chǎn)生看門狗復位。WWDG的喂狗操作必須在計數(shù)器值小于窗口寄存器值時操作,只有該情況下喂狗不會產(chǎn)生復位。
窗口值
如圖3所示,WWDG的上限窗口值由配置寄存器(WWDG_CFGR)的W位控制,為保證窗口的價值,上限窗口值必須大于0x40且小于等于0x7F。
提前喚醒中斷
利用提前喚醒中斷(EWI) 可以避免復位并且重載計數(shù)器。操作配置寄存器(WWDG_CFGR)中的EWI位開啟中斷,當計數(shù)器遞減到0x40時,產(chǎn)生提前喚醒中斷,可以在中斷處理函數(shù)中向控制寄存器(WWDG_CR)重載計數(shù)器的值來達到喂狗的目的,從而防止復位。
2、實驗
本實驗配置WWDG計數(shù)器時鐘的預分頻系數(shù)為8分頻,配置重載計數(shù)器窗口的上限值為0x7F,時鐘初始化后,串口打印"wwdg_basic example.",初始化WWDG后使能提前喚醒中斷(EWI),在中斷處理函數(shù)中判斷是否已經(jīng)重裝載計數(shù)器到指定次數(shù),若未達到則重裝載一次WWDG計數(shù)器,并記錄重裝載次數(shù),達到指定次數(shù)則不再重裝載計數(shù)器。
初始化WWDG后進入死循環(huán),每經(jīng)過一段延時,串口打印一個".",表示CPU仍在工作,直到WWDG復位,串口再次打印"wwdg_basic example."。
啟用WWDG外設時鐘 enable_clock()
實驗使用WWDG,串口打印輸出結果,串口使用引腳屬于GPIOA組,因此需要啟用WWDG、UART1及GPIOA的外設時鐘。
void enable_clock() { /* Enable WWDG clock. */ RCC->APB1ENR |= RCC_APB1_PERIPH_WWDG; /* Enable GPIOA clock. */ RCC->AHB1ENR |= RCC_AHB1_PERIPH_GPIOA; /* Enable UART1 clock. */ RCC->APB2ENR |= RCC_APB2_PERIPH_UART1; }
配置引腳 pin_init()
由于實驗現(xiàn)象通過串口顯示,故配置UART的TX(PA9)與RX(PA10)引腳。
void pin_init() { /* PA9 - UART_TX. */ GPIOA->CRH = ~GPIO_CRH_MODE9_MASK; GPIOA->CRH = ~GPIO_CRH_CNF9_MASK; GPIOA->CRH |= GPIO_CRH_MODE9(GPIO_Speed_50MHz); GPIOA->CRH |= GPIO_CRH_CNF9(GPIO_PinMode_AF_PushPull); GPIOA->AFRH = ~GPIO_AFRH_AFR_MASK; GPIOA->AFRH |= (GPIO_AF_1 << GPIO_CRH_MODE9_SHIFT); /* PA10 - UART_RX. */ GPIOA->CRH = ~GPIO_CRH_MODE10_MASK; GPIOA->CRH = ~GPIO_CRH_CNF10_MASK; GPIOA->CRH |= GPIO_CRH_CNF10(GPIO_PinMode_In_Floating); GPIOA->AFRH |= (GPIO_AF_1 << GPIO_CRH_MODE10_SHIFT); }
UART初始化 uart_init()
初始化UART,配置時鐘頻率、波特率、數(shù)據(jù)長度、停止位、傳輸模式及是否使用校驗。
void uart_init() { /* Clear the corresponding bit to be used. */ UART1->CCR = ~( UART_CCR_PEN_MASK | UART_CCR_PSEL_MASK | UART_CCR_SPB0_MASK | UART_CCR_SPB1_MASK | UART_CCR_CHAR_MASK ); UART1->GCR = ~( UART_GCR_AUTOFLOWEN_MASK | UART_GCR_RXEN_MASK | UART_GCR_TXEN_MASK ); /* WordLength. */ UART1->CCR |= UART_CCR_CHAR_MASK; /* XferMode. */ UART1->GCR |= (UART_XferMode_RxTx << UART_GCR_RXEN_SHIFT); /* Setup baudrate, BOARD_DEBUG_UART_FREQ = 48000000u, BOARD_DEBUG_UART_BAUDRATE = 9600u. */ UART1->BRR = (BOARD_DEBUG_UART_FREQ / BOARD_DEBUG_UART_BAUDRATE) / 16u; UART1->FRA = (BOARD_DEBUG_UART_FREQ / BOARD_DEBUG_UART_BAUDRATE) % 16u; /* Enable UART1. */ UART1->GCR |= UART_GCR_UARTEN_MASK; }
WWDG初始化 wwdg_init()
操作配置寄存器(WWDG_CFGR)的WDGPB位配置預分頻系數(shù)為8分頻,W位配置重載計數(shù)器窗口的上限值為0x7F,EWI位置1使能提前喚醒中斷,操作控制寄存器(WWDG_CR)的WDGA位置1,啟動看門狗。
void wwdg_init() { WWDG->CFGR = WWDG_CFGR_WDGTB(WWDG_Prescaler_8) | WWDG_CFGR_W(WWDG_UPPER_LIMIT); /* WWDG_UPPER_LIMIT = 0x7F, WWDG_Prescaler_8 = 3u. */ NVIC_EnableIRQ(WWDG_IWDG_IRQn); WWDG->CFGR |= WWDG_CFGR_EWI_MASK; WWDG->CR |= WWDG_CR_WDGA_MASK; }
中斷服務程序 WWDG_IWDG_IRQHandler()
中斷服務程序中判斷是否已經(jīng)重裝載計數(shù)器到指定次數(shù),若未達到則重裝載一次WWDG計數(shù)器,并記錄重裝載次數(shù),若達到則不再重裝載計數(shù)器。向狀態(tài)寄存器(WWDG_SR)的EWIF位寫0,清除提前喚醒中斷標志。
void WWDG_IWDG_IRQHandler(void) { uint32_t status = WWDG->SR; if ( 0 != (WWDG_SR_EWIF_MASK status) ) { WWDG->SR = ~WWDG_SR_EWIF_MASK;; } /* Stop reload WWDG counter aftert reload WWDG counter BOARD_WWDG_RELOAD_TIMES times. */ if (100u > reload_times) /* uint32_t reload_times = 0u. */ { reload_times++; WWDG->CR = (WWDG->CR ~WWDG_CR_T_MASK) | WWDG_CR_T(WWDG_RELOAD_VALUE); /* WWDG_RELOAD_VALUE = 0x7f. */ } }
延時 soft_delay()
本實驗設置初始化后進入while循環(huán),循環(huán)中隔一段延時進行一次串口打印,表示當前CPU仍在工作,故編寫軟件延時。
void soft_delay(uint32_t delay) { for(uint32_t i = 0u; i < delay; i++) { for(uint32_t j = 0u; j < 10000u; j++) { __NOP(); } } }
main()函數(shù)
main()函數(shù)結合上述操作,串口打印"wwdg_basic example.",初始化WWDG并使能提前喚醒中斷后進入死循環(huán),循環(huán)中每經(jīng)過一段延時串口將打印一個 “.” ,表示CPU仍在工作,直到WWDG復位,實驗現(xiàn)象如圖4所示。
void main() { enable_clock(); pin_init(); uart_init(); printf("rnwwdg_basic example.rn"); wwdg_init(); while (1) { printf("."); soft_delay(100u); } }
來源:靈動MM32MCU
免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯(lián)系小編進行處理
審核編輯 黃宇
-
看門狗
+關注
關注
10文章
562瀏覽量
70813
發(fā)布評論請先 登錄
相關推薦
評論