看门狗定时器

  • 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秒。

posted on 2016-04-12 17:39  陌鉎こ城sHi  阅读(2524)  评论(0编辑  收藏  举报