Chinaunix首页 | 论坛 | 博客
  • 博客访问: 605615
  • 博文数量: 165
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1554
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-23 22:57
个人简介

我本仁慈,奈何苍天不许

文章分类

全部博文(165)

文章存档

2018年(1)

2016年(33)

2015年(5)

2014年(34)

2013年(92)

分类: 嵌入式

2016-07-21 14:11:54

原文地址:BLE-NRF51822教程8-动态广播 作者:ifndef

本讲接收如何实现动态广播。

教程基于 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就可以了


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

阅读(779) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~