在裸机程序中,有timer例子,直接使用没有任何问题,但是不能直接用在BLE程序中。在BLE程序中使用就有些麻烦,BLE本身也使用了定时器,如果APP再使用算是借用。SDK12的BLE例子中也没有找到完整的例子。网上找到nrf52 Application Timer和nrf52-添加定时任务。
前者例子:
// General application timer settings.
#define APP_TIMER_PRESCALER 16 // Value of the RTC1 PRESCALER register.
#define APP_TIMER_MAX_TIMERS 2 // Maximum number of timers in this application.
#define APP_TIMER_OP_QUEUE_SIZE 3 // Size of timer operation queues.
static app_timer_id_t m_led_a_timer_id;
static void lfclk_request(void)
{
uint32_t err_code = nrf_drv_clock_init(NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_clock_lfclk_request();
}
// Timeout handler for the repeated timer
static void timer_a_handler(void * p_context)
{
nrf_drv_gpiote_out_toggle(LED_1_PIN);
}
// Create timers
static void create_timers()
{
uint32_t err_code;
// Create timers
err_code = app_timer_create(&m_led_a_timer_id,
APP_TIMER_MODE_REPEATED,
timer_a_handler);
APP_ERROR_CHECK(err_code);
}
int main()
{
// Request LF clock.
lfclk_request();
// Initialize the application timer module.
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
create_timers();
uint32_t err_code = app_timer_start(m_led_a_timer_id, APP_TIMER_TICKS(200, APP_TIMER_PRESCALER), NULL);
APP_ERROR_CHECK(err_code);
while(1);
}
在experimental_ble_app_buttonless_dfu
找到一些APP Timer
使用的蛛丝马迹,重点有timer_init
和application_timers_start
两个函数。
/**@brief Function for the Timer initialization.
*
* @details Initializes the timer module.
*/
static void timers_init(void)
{
// Initialize timer module, making it use the scheduler
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
// Create timers.
/* YOUR_JOB: Create any timers to be used by the application.
Below is an example of how to create a timer.
For every new timer needed, increase the value of the macro APP_TIMER_MAX_TIMERS by
one.
uint32_t err_code;
err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, handle);
APP_ERROR_CHECK(err_code);
*/
}
/**@brief Function for starting timers.
*/
static void application_timers_start(void)
{
/* YOUR_JOB: Start your timers. below is an example of how to start a timer.
uint32_t err_code;
err_code = app_timer_start(m_app_timer_id, TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
*/
}
将其uncomment
之后并不能正常使用,BLE都搜索不到了。Debug之后定位到app_timer_create
反回了一个0x08
,而不是成功的0x00
。
过一段时间再去搜索原因,有一个帖子提到需要使用APP_TIMER_DEF(m_app_timer_id);
的方式取代如下方式:
static app_timer_id_t m_timer_id;
这样就好了,完整如下:
//static app_timer_id_t m_app_timer_id;
APP_TIMER_DEF(m_app_timer_id);
/**@brief Function for the Timer initialization.
*
* @details Initializes the timer module.
*/
static void timers_init(void)
{
// Initialize timer module, making it use the scheduler
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
// Create timers.
/* YOUR_JOB: Create any timers to be used by the application.
Below is an example of how to create a timer.
For every new timer needed, increase the value of the macro APP_TIMER_MAX_TIMERS by
one.
*/
uint32_t err_code;
err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, handle);
APP_ERROR_CHECK(err_code);
}
#define TIMER_INTERVAL 20
/**@brief Function for starting timers.
*/
static void application_timers_start(void)
{
/* YOUR_JOB: Start your timers. below is an example of how to start a timer. */
uint32_t err_code;
err_code = app_timer_start(m_app_timer_id, TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
其他被证实为假的假设:
APP_TIMER_MAX_TIMERS
需要+1
,在sdk12
版本中,似乎并没有使用到该宏;- 需要
nrf_drv_clock_lfclk_request
,实测并不需要调用;