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)                

將原來的改爲如果想創建更多的定時器,同樣也要改大這裏的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章