BLE-NRF51822教程8-软件定时器的使用

本讲教程还是会基于 9.0 sdk中的uart例子。 在该例子上使用 sdk中自带的软件定时器来实现一些功能

Uart例子在sdk 中如下目录

XXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_uart 


首先 了解一下相关API

Sdk中的app timer(软件定时器) 是用51822中的RTC来模拟出的一个定时器队列来实现通过一个硬件RTC来模拟多个软件定时器。

使用app timer模块之前需要调用

 

uint32_t app_timer_init

(

uint32_t 

prescaler,

   

uint8_t 

max_timers,

   

uint8_t 

op_queues_size,

   

void * 

p_buffer,

   

app_timer_evt_schedule_func_t 

evt_schedule_func 

 

)

   

 

来初始化模块,通常都不直接使用该函数,而是使用SDK中提供的宏。

这个宏会根据帮你的参数申请合适的buff然后再调用app_timer_init函数

#define APP_TIMER_INIT

(

 

PRESCALER,


 

 

MAX_TIMERS,

   

 

OP_QUEUES_SIZE,

   

 

SCHEDULER_FUNC 

 

)

   

Value:

do {             \

    static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((MAX_TIMERS), \

                          (OP_QUEUES_SIZE) + 1), \

                            sizeof(uint32_t))]; \

        uint32_t ERR_CODE = app_timer_init((PRESCALER), \

                          (MAX_TIMERS), \

                          (OP_QUEUES_SIZE) + 1, \

                          APP_TIMER_BUF, \

                          SCHEDULER_FUNC); \

                          APP_ERROR_CHECK(ERR_CODE); \

     } while (0)

 然后就可以创建自己的定时器了。

uint32_t app_timer_create

(

app_timer_id_t * 

p_timer_id,

   

app_timer_mode_t 

mode,

   

app_timer_timeout_handler_t 

timeout_handler 

 

) 

 

可以通过mode模式来选择是只运行一次还是周期性的定时器。

APP_TIMER_MODE_SINGLE_SHOT,

APP_TIMER_MODE_REPEATED

Timeout_handler为注册的回调函数,在定时到期后执行。


定时器创建完成后需要主动调用开始函数

uint32_t app_timer_start(app_timer_id_t timer_id,uint32_t timeout_ticks,void * p_context)

定时时间timeout_ticks需要通过宏APP_TIMER_TICKS(MS, PRESCALER)来或得,MS为需要定时的ms, PRESCALER就是上面的初始化模块时的参数PRESCALER

P_context为传递给回调函数的参数。 在定时到期执行定时函数时这个参数会作为他的参数。


下面我们在uart工程的基础上创建一个定时器,这个定时器在手机使能了rx特征值的notify功能后启动,然后周期性的递增发送一个数据给手机

 

Uart工程中app timer模块的初始化已经有了,我们只要创建一个定时器然后在手机使能notify时开启他就行了。

 

添加如下变量和函数。

app_timer_id_t my_test_timer;

uint8_t g_send_data = 0;

void my_timer_handler(void *params){

    ble_nus_string_send(&m_nus, &g_send_data, 1);

    g_send_data++;

}

修改main函数,初始化最后创建定时器。

int main(void)

{

    uint32_t err_code;

    bool erase_bonds;

    uint8_t start_string[] = START_STRING;

    // Initialize.    APP_TIMER_INIT(APP_TIMER_PRESCALER,APP_TIMER_MAX_TIMERS,APP_TIMER_OP_QUEUE_SIZE,false);                 //原工程中已经初始化了app timer模块

    uart_init();

    buttons_leds_init(&erase_bonds);

    ble_stack_init();

    gap_params_init();

    services_init();

    advertising_init();

    conn_params_init();

     printf("start");

    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);

    APP_ERROR_CHECK(err_code);

   //添加创建定时器代码

   err_code = app_timer_create(&my_test_timer,APP_TIMER_MODE_REPEATED, my_timer_handler);    

    printf("create timere err_code:%d\r\n",err_code);

    // Enter main loop.

    for (;;)

    {

        power_manage();

    }

}

 

然后 在 ble_nus.c 中 找到on_write函数添加红色部分

extern app_timer_id_t my_test_timer;  //声明下变量

static void on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt)

{

    int err_code;

    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

    if ( (p_evt_write->handle == p_nus->rx_handles.cccd_handle)&&(p_evt_write->len == 2))

    {

        if (ble_srv_is_notification_enabled(p_evt_write->data))

        {

            p_nus->is_notification_enabled = true;

           //定时1s,   PRESCALER直接填 0

               app_timer_start(my_test_timer,  APP_TIMER_TICKS(1000, 0), NULL);

        }

        else

        {

            p_nus->is_notification_enabled = false;

        }

    }

    else if ((p_evt_write->handle == p_nus->tx_handles.value_handle) &&(p_nus->data_handler != NULL)

            )

    {

      ……………………………………….

    }

    else

    {

        // Do Nothing. This event is not relevant for this service.

    }

}

 

 

现在下载程序后,手机连接,然后点使能Notify后就能周期收到数据了。

 

如果创建timer出错。是允许创建的定时器已经达到最大值了,可以修改一下宏。

Main.c中的

#define APP_TIMER_MAX_TIMERS    (3 + BSP_APP_TIMERS_NUMBER)                

将原来的改为如果想创建更多的定时器,同样也要改大这里的值

你可能感兴趣的:(蓝牙开发)