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

文章来源:http://blog.chinaunix.net/uid-28852942-id-5586540.html


本讲教程还是会基于 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)                

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值