您的位置:首页 > 其它

BLE-NRF51822教程9-动态广播

2016-03-04 14:31 281 查看
本讲接收如何实现动态广播。

教程基于 9.0 sdk中的 Uart例子。

实现动态广播的方法是  广播->停止广播->修改参数->重启广播

所以我们通过一个定时器来周期性的  关闭广播然后再修改广播数据之后再开启广播。

Sdk 9.0中的广播搞了好几个模式,做的有点麻烦,所以我对他做了比较大的改动。

首先 在main.c中 中的advertising_init函数需要改动。

主要修改还添加了红色部分。将 flag 改为了GENERAL。后面又将广播超时设置为0从而实现无线广播。

去掉了根据广播模式来设置广播数据的函数以及对 扫描响应数据的设置。

void advertising_init(void)

{

    uint32_t      err_code;

    ble_advdata_t advdata;

    ble_advdata_t scanrsp;

    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type          = BLE_ADVDATA_FULL_NAME;

    advdata.include_appearance = false;

    advdata.flags      = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

   static ble_advdata_manuf_data_t manuf_data;

   static uint8_t mydata = 0;  //这里用的是静态数据

                            //这里做的动态广播就是每次调用这个函

                            //数,广播数据中的厂商定义字段都会加1

  

   manuf_data.company_identifier = 0xffaa;

   manuf_data.data.size = 1;

   manuf_data.data.p_data = &mydata;

  

   mydata++; //每次调用后加1

   advdata.p_manuf_specific_data = &manuf_data;

   err_code = ble_advdata_set(&advdata, NULL);

    APP_ERROR_CHECK(err_code);

}

然后是启动广播函数。 Main 函数中用的是ble_advertising_start。

我们这里不用。直接实现一个自己的简单函数

void myadv_start(void){

   

    ble_gap_adv_params_t adv_params;

   

    adv_params.interval = 1600; //这里广播间隔设置为 1s

    adv_params.timeout = 0;//这里设置0和上面的flag配合实现无线广播

    adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;

    adv_params.channel_mask.ch_37_off = 0;

    adv_params.channel_mask.ch_38_off = 0;

    adv_params.channel_mask.ch_39_off = 0;

   

    adv_params.type        = BLE_GAP_ADV_TYPE_ADV_IND;

    adv_params.p_peer_addr = NULL;

    adv_params.fp          = BLE_GAP_ADV_FP_ANY;

    adv_params.p_whitelist = NULL;

   

    sd_ble_gap_adv_start(&adv_params);

   

}

之后我们做一个定时器。定时器的作用是以2s为周期 来关闭修改广播参数然后启动广播

在main 函数中做如下修改,创建一个 2s定时器 my_timer,并且开启它

int main(void)

{

    uint32_t err_code;

    bool erase_bonds;

    uint8_t  start_string[] = START_STRING;

    app_timer_id_t my_timer;

    // Initialize.

   

    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS,                                  APP_TIMER_OP_QUEUE_SIZE, false);

    uart_init();

    app_timer_create(&my_timer,APP_TIMER_MODE_REPEATED,

                               my_timer_handler);

    buttons_leds_init(&erase_bonds);

    ble_stack_init();

    gap_params_init();

    services_init();

    advertising_init();

    conn_params_init();

  

   

    app_timer_start(my_timer, APP_TIMER_TICKS(2000,APP_TIMER_PRESCALER), NULL);

  

    myadv_start(); //这里用的自己定义的启动广播函数

    for (;;)

    {

        power_manage();

    }

}

然后实现自己的 定时器的溢出处理函数

void my_timer_handler(void *p_contex){

    int i =50;

    sd_ble_gap_adv_stop();   //关广播

    advertising_init();      //修改厂商自定义字段中的数据

    while(i--);

    myadv_start();           //开启广播

}

这里做的动态广播是动态修改广播数据中的 厂商自定义字段。每次调用

advertising_init 函数的时候厂商自定义字段的值都会递增。在advertising_init函数中有注释说明

到这里动态广播要做的事已经做完了。

不过在uart例子中还需要做一个改动,我们创建了一个自己的timer,不过uart例子中定义的
允许使用的最大的
 timer数就是它已经使用的数量,所以我们再添加自己的timer会出错。

修改办法:找到main.c文件中的APP_TIMER_MAX_TIMERS宏将其增大1就可以了

之后烧录程序就能看到广播数据中的厂商自定义字段在动态改变了

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: