看門狗定時器
- NRF51822 的看門狗定時器是倒計數器, 當計數值減少到 0 時產生 TIMEOUT 事件。
- 通過 START task 來啟動看門狗定時器。
- 看門狗定時器啟動時,如沒有其他 32.768KHz 時鍾源提供時鍾,看門狗定時器會強制打開 32.768KHz RC 振盪器。
- 默認情況下,看門狗定時器會在 CPU 睡眠期間,或是 debugger 將 CPU 暫停的時候保持運行。但是,可以通過配置看門狗定時器,使其在 CPU 睡眠期間,或是debugger 將 CPU 暫停的時候自動暫停。
- 看門狗定時器超時周期:timeout [s] = ( CRV + 1 ) / 32768。
使用的代碼為nRF51_SDK_10.0.0_dc26b5e\examples\peripheral\wdt
1 /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 * 3 * The information contained herein is property of Nordic Semiconductor ASA. 4 * Terms and conditions of usage are described in detail in NORDIC 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 * 7 * Licensees are granted free, non-transferable use of the information. NO 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 * the file. 10 * 11 */ 12 13 /** @file 14 * @defgroup nrf_dev_wdt_example_main main.c 15 * @{ 16 * @ingroup nrf_dev_wdt_example 17 * @brief WDT Example Application main file. 18 * 19 * This file contains the source code for a sample application using WDT. 20 * 21 */ 22 23 #include <stdbool.h> 24 #include <stdint.h> 25 26 #include "nrf.h" 27 #include "bsp.h" 28 #include "app_timer.h" 29 #include "app_error.h" 30 #include "nrf_drv_wdt.h" 31 #include "nrf_drv_clock.h" 32 #include "nrf_delay.h" 33 #include "app_util_platform.h" 34 35 #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ 36 #define APP_TIMER_OP_QUEUE_SIZE 2 /**< Size of timer operation queues. */ 37 #define FEED_BUTTON_ID 0 /**< Button for feeding the dog. */ 38 39 nrf_drv_wdt_channel_id m_channel_id; 40 41 /** 42 * @brief WDT events handler. 43 */ 44 void wdt_event_handler(void) 45 { 46 LEDS_OFF(LEDS_MASK); 47 48 //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs 49 } 50 51 /** 52 * @brief Assert callback. 53 */ 54 void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) 55 { 56 LEDS_OFF(LEDS_MASK); 57 while(1); 58 } 59 60 /** 61 * @brief BSP events callback. 62 */ 63 void bsp_event_callback(bsp_event_t event) 64 { 65 switch(event) 66 { 67 case BSP_EVENT_KEY_0: 68 nrf_drv_wdt_channel_feed(m_channel_id); 69 break; 70 71 default : 72 //Do nothing. 73 break; 74 } 75 } 76 77 /** 78 * @brief Function for main application entry. 79 */ 80 int main(void) 81 { 82 uint32_t err_code = NRF_SUCCESS; 83 84 //BSP configuration for button support: button pushing will feed the dog. 85 err_code = nrf_drv_clock_init(NULL); 86 APP_ERROR_CHECK(err_code); 87 nrf_drv_clock_lfclk_request(); 88 89 APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false); 90 err_code = bsp_init(BSP_INIT_BUTTONS, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), bsp_event_callback); 91 APP_ERROR_CHECK(err_code); 92 93 //Configure all LEDs on board. 94 LEDS_CONFIGURE(LEDS_MASK); 95 LEDS_OFF(LEDS_MASK); 96 97 //Indicate program start on LEDs. 98 for(uint32_t i = 0; i < LEDS_NUMBER; i++) 99 { nrf_delay_ms(200); 100 LEDS_ON(BSP_LED_0_MASK << i); 101 } 102 err_code = bsp_buttons_enable(); 103 APP_ERROR_CHECK(err_code); 104 105 //Configure WDT. 106 nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG; 107 err_code = nrf_drv_wdt_init(&config, wdt_event_handler); 108 APP_ERROR_CHECK(err_code); 109 err_code = nrf_drv_wdt_channel_alloc(&m_channel_id); 110 APP_ERROR_CHECK(err_code); 111 nrf_drv_wdt_enable(); 112 113 while(1) 114 { 115 __SEV(); 116 __WFE(); 117 __WFE(); 118 } 119 } 120 121 /** @} */
在 nrf_drv_config.h文件中可以看到WDT的默認定義
/* WDT */ #define WDT_ENABLED 1 #if (WDT_ENABLED == 1) #define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP #define WDT_CONFIG_RELOAD_VALUE 2000 #define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH #endif
/** * @brief Function for setting the watchdog reload value. * * @param[in] reload_value Watchdog counter initial value. */ __STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) { NRF_WDT->CRV = reload_value; } ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, nrf_wdt_event_handler_t wdt_event_handler) { ASSERT(wdt_event_handler != NULL); m_wdt_event_handler = wdt_event_handler; if (m_state == NRF_DRV_STATE_UNINITIALIZED) { m_state = NRF_DRV_STATE_INITIALIZED; } else { return NRF_ERROR_INVALID_STATE; // WDT already initialized } if (p_config == NULL) { p_config = &m_default_config; } nrf_wdt_behaviour_set(p_config->behaviour); nrf_wdt_reload_value_set((p_config->reload_value * 32768) / 1000); nrf_drv_common_irq_enable(WDT_IRQn, p_config->interrupt_priority); return NRF_SUCCESS; }
CRV值是32768*2000/1000= 65536。
當把給WDT獲得上述值(65536+1)/32768=2秒。