加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

nrf51822---主从一体通信(3)

(2017-02-04 16:02:51)
分类: 蓝牙
from:http://blog.csdn.net/a369000753/article/details/51220956

目的

   学习nrf51822主机和从机通信

2.分析

    nrf51822---主从通信(1)和nrf51822---主从通信(2)都是在已知服务的基础上面来找的。但是在实际中并不知道对方的属性,可能只告诉你要连接蓝牙的名字。那怎么办呢???

 

3.平台:

协议栈版本:SDK10.0.0

编译软件:keil 5.12

硬件平台:nrf51822最小系统

例子:SDK 10.0.0\examples\ble_peripheral\ble_app_uart\pca10028\s110\arm4 从机例子

          SDK10.0\examples\ble_central_and_peripheral\experimental\ble_app_hrs_rscs_relay\pca10028\s130\arm4 做主机

4步骤.

  首先来大概分析下代码。

    首先在主函数里.2个从机,控制服务初始化的过程,然后扫描开始,广播开始,即主从一体

  

  1. int main(void 
  2.  
  3.     ret_code_t err_code;  
  4.     bool       erase_bonds;  
  5.   
  6.     err_code NRF_LOG_INIT();  
  7.     APP_ERROR_CHECK(err_code);  
  8.   
  9.     NRF_LOG_PRINTF("Relay Example\r\n");  
  10.   
  11.     APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);  
  12.     buttons_leds_init(&erase_bonds);  
  13.   
  14.     if (erase_bonds == true 
  15.      
  16.         NRF_LOG("Bonds erased!\r\n");  
  17.      
  18.     ble_stack_init();  
  19.   
  20.     peer_manager_init(erase_bonds);  
  21.   
  22.     db_discovery_init();  
  23.     hrs_c_init();  //HES初始化  
  24.     rscs_c_init(); //rscs初始化  
  25.   
  26.     gap_params_init();  
  27.     conn_params_init();  
  28.     services_init();  
  29.     advertising_init();  
  30.   
  31.       
  32.     scan_start(); //扫描开始  
  33.   
  34.     // Turn on the LED to signal scanning.  
  35.     LEDS_ON(CENTRAL_SCANNING_LED);  
  36.   
  37.     // Start advertising.  
  38.     err_code ble_advertising_start(BLE_ADV_MODE_FAST); //广播初始化  
  39.     APP_ERROR_CHECK(err_code);  
  40.   
  41.     for (;;)  
  42.      
  43.         // Wait for BLE events.  
  44.         power_manage();  
  45.      
  46.  

 


接下来看扫描到了广播,产生BLE_GAP_EVT_ADV_REPORT事件代码:


 

  1. case BLE_GAP_EVT_ADV_REPORT:  
  2.         
  3.            uint32_t err_code;  
  4.            data_t   adv_data;  
  5.            data_t   type_data;  
  6.   
  7.            // For readibility.  找到扫描的地址  
  8.            const ble_gap_addr_t  const peer_addr &p_gap_evt->params.adv_report.peer_addr;  
  9.   
  10.            // Initialize advertisement report for parsing.  
  11.            adv_data.p_data     (uint8_t *)p_gap_evt->params.adv_report.data;  //扫描广播的数据地址  
  12.            adv_data.data_len   p_gap_evt->params.adv_report.dlen;  //扫描广播的长度  
  13.            //找标识符为BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE的数据地址和长度  
  14.            err_code adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,  
  15.                                        &adv_data,  
  16.                                        &type_data);  
  17.      if (err_code != NRF_SUCCESS)  
  18.             
  19.                // Look for the services in 'complete' if it was not found in 'more available'.  
  20.                err_code adv_report_parse(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,  
  21.                                            &adv_data,  
  22.                                            &type_data);  
  23.   
  24.                if (err_code != NRF_SUCCESS)  
  25.                 
  26.                    // If we can't parse the data, then exit.  
  27.                    break 
  28.                 
  29.             
  30.            // Verify if any UUID match the Heart rate or Running speed and cadence services.  
  31.            for (uint32_t u_index 0; u_index (type_data.data_len UUID16_SIZE); u_index++)  
  32.             
  33.                bool        do_connect false 
  34.                uint16_t    extracted_uuid;  
  35.                  //复制出UUID到extracted  
  36.                UUID16_EXTRACT(&extracted_uuid, &type_data.p_data[u_index UUID16_SIZE]);  
  37.                 //判断UUID是不是心率的UUID并且看是否已经连上了  
  38.                if ((extracted_uuid      == BLE_UUID_HEART_RATE_SERVICE) &&  
  39.                    (m_conn_handle_hrs_c == BLE_CONN_HANDLE_INVALID))  
  40.                              do_connect true 
  41.                    memcpy(&periph_addr_hrs, peer_addr, sizeof(ble_gap_addr_t)); //复制扫描的蓝牙地址到periph_addr_hrs  
  42.                   //或者UUID是不是RSCS的UUID并且没有连上  
  43.                else if ((extracted_uuid       == BLE_UUID_RUNNING_SPEED_AND_CADENCE) &&  
  44.                         (m_conn_handle_rscs_c == BLE_CONN_HANDLE_INVALID))  
  45.                 
  46.                    do_connect true 
  47.                    memcpy(&periph_addr_rsc, peer_addr, sizeof(ble_gap_addr_t)); //复制蓝牙地址  
  48.                 
  49.   
  50.                if (do_connect)  
  51.                 
  52.                    // Initiate connection.   //连接这地址的设备  
  53.                    err_code sd_ble_gap_connect(peer_addr, &m_scan_param, &m_connection_param);  
  54.                    if (err_code != NRF_SUCCESS)  
  55.                     
  56.                        APPL_LOG("[APPL]: Connection Request Failed, reason %d\r\n"err_code);  
  57.                     
  58.                 
  59.             
  60.        break// BLE_GAP_ADV_REPORT  

 

 如果连上了设备则产生BLE_GAP_EVT_CONNECTED事件

  

  1. case BLE_GAP_EVT_CONNECTED:  
  2.       
  3.          uint32_t err_code;  
  4.   
  5.          // For readability.  
  6.          const ble_gap_addr_t const peer_addr &p_gap_evt->params.connected.peer_addr;  //找到蓝牙的地址  
  7.   
  8.                                                                                     if(memcmp(&periph_addr_hrs, peer_addr, sizeof(ble_gap_addr_t)) == 0)  //连接上的蓝牙地址和和被连接的蓝牙地址对比 一直则正确  
  9.           
  10.              NRF_LOG_PRINTF("HRS central connected\r\n");  
  11.              // Reset the peer address we had saved.  
  12.              memset(&periph_addr_hrs, 0, sizeof(ble_gap_addr_t));  
  13.   
  14.              m_conn_handle_hrs_c p_gap_evt->conn_handle;  //保存连接的handle  这个很总有可以用来区别哪个设备  
  15.   
  16.              NRF_LOG_PRINTF("Starting DB discovery for HRS\r\n");  
  17.              err_code ble_db_discovery_start(&m_ble_db_discovery_hrs, p_gap_evt->conn_handle);  //开始发现服务  
  18.              APP_ERROR_CHECK(err_code);  
  19.                     else if(memcmp(&periph_addr_rsc, peer_addr, sizeof(ble_gap_addr_t)) == 0)  "font-family: Arial, Helvetica, sans-serif;">//连接上的蓝牙地址和和被连接的蓝牙地址对比 一直则正确  
  20.           
  21.              NRF_LOG_PRINTF("RSC central connected\r\n");  
  22.              // Reset the peer address we had saved.  
  23.              memset(&periph_addr_rsc, 0, sizeof(ble_gap_addr_t));   
  24.   
  25.              m_conn_handle_rscs_c p_gap_evt->conn_handle;//保存连接的handle  
  26.   
  27.              NRF_LOG_PRINTF("Starting DB discovery for RSCS\r\n");  
  28.              err_code ble_db_discovery_start(&m_ble_db_discovery_rsc, p_gap_evt->conn_handle);  //开始扫描服务设备  
  29.              APP_ERROR_CHECK(err_code);  
  30.           
  31.   
  32.            
  33.          LEDS_ON(CENTRAL_CONNECTED_LED);  
  34.          if (ble_conn_state_n_centrals() == MAX_CONNECTED_CENTRALS)//判断连接的设备是否为设定的设备值  
  35.           
  36.              LEDS_OFF(CENTRAL_SCANNING_LED);//  
  37.           
  38.          else          
  39.              // Resume scanning.  
  40.              LEDS_ON(CENTRAL_SCANNING_LED);  
  41.              scan_start();  //继续扫描  
  42.           
  43.      break// BLE_GAP_EVT_CONNECTED  

 


断开某设备。会产生BLE_GAP_EVT_DISCONNECTED事件,

 

  1. case BLE_GAP_EVT_DISCONNECTED:  
  2.        
  3.           uint8_t n_centrals;  
  4.   
  5.           if (p_gap_evt->conn_handle == m_conn_handle_hrs_c) //判断断开的设备是哪个设备,是否为HRS设备。找出对应的handle  
  6.            
  7.               NRF_LOG_PRINTF("HRS central disconnected (reason: %d)\r\n" 
  8.                      p_gap_evt->params.disconnected.reason);  
  9.   
  10.               m_conn_handle_hrs_c BLE_CONN_HANDLE_INVALID;  //handle初始化  
  11.            
  12.           else if(p_gap_evt->conn_handle == m_conn_handle_rscs_c) //判断断开的设备是不是RSCS设备  
  13.            
  14.               NRF_LOG_PRINTF("RSC central disconnected (reason: %d)\r\n" 
  15.                      p_gap_evt->params.disconnected.reason);  
  16.   
  17.               m_conn_handle_rscs_c BLE_CONN_HANDLE_INVALID; //handle初始化  
  18.            
  19.           // Start scanning  
  20.           scan_start(); //这里会不会冲突。  
  21.   
  22.           // Update LEDs status.  
  23.           LEDS_ON(CENTRAL_SCANNING_LED);  
  24.           n_centrals ble_conn_state_n_centrals();  
  25.           if (n_centrals == 0)  
  26.            
  27.               LEDS_OFF(CENTRAL_CONNECTED_LED);  
  28.            
  29.       break// BLE_GAP_EVT_DISCONNECTED  

以上代码发现,如果连上了2个设备这个时候,不再scan_start(),在使用中断开了一个设备是否需要从新scan_start()再次连接一个呢?或者又如,值连接了一个设备,并且主机也还在扫描,并且这个连上的设备也断开了,假如调用了scan_start();会怎么样?实验证明无影响。。

 


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有