NRF51822学习笔记之主从通信讲解,另外附加把UUID更改成蓝牙技术联盟的基本UUID

编程入门 行业动态 更新时间:2024-10-24 04:46:35

NRF51822学习笔记之<a href=https://www.elefans.com/category/jswz/34/1768145.html style=主从通信讲解,另外附加把UUID更改成蓝牙技术联盟的基本UUID"/>

NRF51822学习笔记之主从通信讲解,另外附加把UUID更改成蓝牙技术联盟的基本UUID

最近在搞蓝牙主从通信这块,公司里面是有之前的代码的,但是自己想在自己52832开发板上弄一个主从通信。从机板子是52832的,从机代码采用官方的串口例程,主机是公司的51822板子,主机代码也是公司的,因为对这块不熟悉,造成主从不能通信,最后请教老员工才知道,他们把蓝牙服务的UUID更改成蓝牙技术联盟的基本UUID的问题,找到问题后,自己改了一下UUID类型,也就成功了,刚好趁这次机会,把UUID从128bit改成16bit的方式,也做个笔记,写出来。本次运用的sdk依旧是SDK12.3版本。好了,先说简单的更改UUID这块。
1、UUID更改步骤以及注意事项
如果你是使用官方的标准128bitUUID,也就不需要经过这个步骤,但是,如果遇到需要更改的时候,可以参考一下。更改了UUID位数,要注意的是主从通信时候,主机会根据从机的主服务UUID名和类型,来和从机通信的,这点要注意。我们先说从机的更改,主机的更改放在主从通信这块来讲解。
步骤1:在从机串口服务初始化函数里面,我们修改一下红色地方

第一个地方,直接屏蔽掉,
第2的地方,我们要更改一下服务类型,为BLE_UUID_TYPE_BLE
第3,4,5,的地方,我们要更改一下主服务,RX,TX的UUID宏定义

第4,5函数里面更改的地方是一样的,贴出一个就行了

最后,我们更改的地方是广播数组

更改完成以后,我们顺便把广播名更改了,因为此次例程是根据设备名来寻找从机设备的,主机寻找的设备名要和从机的一样。

更改好以后,下载进开发板里面,我们可以看到广播与以前 的不一样的地方。
以前的是:

更改以后是;


到这里,就已经完成了,下面我们开始讲主从通信这块。主从通信例程这块,大家可以对照官网给的例程查看,路径为D:\nRF5_SDK_12.3.0_d7731ad\examples\ble_central_and_peripheral\experimental\ble_app_hrs_rscs_relay;我也是在这个例程上修改的。
1、修改宏定义,其实这个官网例程已经修改好了,也可以不必须修改。

可以看图片上的宏定义,CENTRAL_LINK_COUNT是作为主机时候,可以连接多少设备,PERIPHERAL_LINK_COUNT是作为从机时候,可以连接多少设备。此处均设为1。也就是说,作为从机时候,连接一个主设备。作为主机时候,连接一个从机设备。
2、向下可以到协议栈初始化,协议栈初始化没什么改变,主要是他的回调函数里面,与之前不一样。我们看一下

我们可以看出,作为从机时候,里面的派发函数与之前官网的一样,但是,我们是让他作为主机,这里我们不必过多查看,主要看作为主机时候的三个派发函数:
1、static void on_ble_central_evt(const ble_evt_t * const p_ble_evt) //主机事假派发函数
2、void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery,
const ble_evt_t * const p_ble_evt) //数据发现事件派发函数
3、ble_nus_c_on_ble_evt(&central_to_perihterial, p_ble_evt) //主从通信事件派发函数
我们按照主机发现设备—>连接设备----->数据交互过程讲解。
首先是发现设备:在on_ble_central_evt()函数里面会有报告BLE_GAP_EVT_ADV_REPORT,可以跳过去看一下这个代码

  case BLE_GAP_EVT_ADV_REPORT:{//¼ìÑéÐźÅuint8_t rssi_val = p_ble_evt->evt.gap_evt.params.adv_report.rssi;{if(rssi_val>0xC9){if (strlen(m_target_periph_name) != 0){if (find_adv_name(&p_gap_evt->params.adv_report, m_target_periph_name)){// Initiate connection.err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.peer_addr,&m_scan_params,&m_connection_param);if (err_code != NRF_SUCCESS){NRF_LOG_INFO("Connection Request Failed, reason %d\r\n", err_code);}}}}}
//            else
//            {
//               /** We do not want to connect to two peripherals offering the same service, so when
//                *  a UUID is matched, we check that we are not already connected to a peer which
//                *  offers the same service. */
//                if ((find_adv_uuid(&p_gap_evt->params.adv_report, 0xA8A0)&&
//                     (m_conn_handle_nus_c == BLE_CONN_HANDLE_INVALID)))
//                {
//                    // Initiate connection.
//                    err_code = sd_ble_gap_connect(&p_gap_evt->params.adv_report.peer_addr,
//                                                  &m_scan_params,
//                                                  &m_connection_param);
//                    if (err_code != NRF_SUCCESS)
//                    {
//                        NRF_LOG_INFO("Connection Request Failed, reason %d\r\n", err_code);
//                    }
//                }
//            }} break; // BLE_GAP_ADV_REPORT

在这里后面的通过UUID查找设备我屏蔽掉了,用到按照设备名寻找设备,我们可以看一下函数find_adv_name();


我用RTT打印了一下发现设备名的名称。看到函数,我们可以发现就是获取到设备名以后,通过对比我们设置的需要连接的设备名数组
static const char m_target_periph_name[] = “lvyapeng”;是否一样,
如果一样,就开始进行连接,如果不是,搜索下一个。如果连接成功,就会触发连接事件BLE_GAP_EVT_CONNECTED,还是在这个函数里面,我们可以看一下。

首先判断结构体m_conn_handle_nus_c是否等于BLE_CONN_HANDLE_INVALID,其中,我修改了地方是定义一个全局结构体
static uint16_t m_conn_handle_nus_c = BLE_CONN_HANDLE_INVALID;
官方之前定义了两个,我给删除了,用了自己的,因为后面的主从通信要用到。建议最好用自己定义的,把官网定义的替换掉。

在这里,我定义了一个bool类型的全局变量Send_cmd_flag,来判断是否可以发送数据给从机。函数ble_db_discovery_start()是进行数据发现和连接的功能。因为这些地方都没修改,所以简单讲解一下。后面的两个函数ble_db_discovery_on_ble_evt()和ble_nus_c_on_ble_evt(),也是一样没有修改的地方,不做讲解。

3、蓝牙数据发现初始化

static void db_discovery_init(void)
{ret_code_t err_code = ble_db_discovery_init(db_disc_handler);APP_ERROR_CHECK(err_code);
}

这个没什么好说的,不过,我们要在他的回调里面增加数据发现处理

static void db_disc_handler(ble_db_discovery_evt_t * p_evt)
{
//    ble_rscs_on_db_disc_evt(&m_ble_rsc_c, p_evt);
//    ble_hrs_on_db_disc_evt(&m_ble_hrs_c, p_evt);ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);}

在void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)函数里面,我们要修改的地方在下面

因为这里就是判断哪个服务是自己要进行通信的,之前我们修改了从机的类型和服务UUID,所以这里也要修改。
4、主机到从机数据流向。
nus_c_init();就是初始化主从数据通信这块了,我们可以跳进去看一下

 static void nus_c_init(void)
{uint32_t           err_code;ble_nus_c_init_t   nus_c_init_obj;nus_c_init_obj.evt_handler = ble_nus_c_evt_handler;err_code = ble_nus_c_init(&m_ble_nus_c, &nus_c_init_obj);APP_ERROR_CHECK(err_code);
}

这些就是主从通信数据交互的初始化,、因为从机修改了服务UUID和类型,这里也要修改,具体如下

步骤和从机一样,把服务类型和uuID修改了

简单修改就行,这里主要注意他的回调函数。
static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)

两者进行数据交互的时候,首先是触发数据发现事件BLE_NUS_C_EVT_DISCOVERY_COMPLETE
如果需要从机发送数据给主机,就使能rx_notify。使能以后,就可接收数据,触发BLE_NUS_C_EVT_NUS_RX_EVT事件,这里我只是打印一个数据就行了。

这两个函数,ble_nus_c_handles_assign是获得校验从机服务参数的
ble_nus_c_rx_notif_enable是发现有RX通知特性,就打开RX使能,进行数据接收。
4、当主从连接好以后,就可以使用发送函数ble_nus_c_string_send(),我在测试过程中,发现虽然我的标志位Send_cmd_flag置1,主循环判断标志位,然后发送,但是会出现发送失败现象,经过测试,发现需要在连接成功以后,延时一段时间在发送才行,我是延时1s在发送数据的。

uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)

发送数据。
5、主机开始扫描

static void adv_scan_start(void)
{ret_code_t err_code;uint32_t count;//check if there are no flash operations in progressprintf"scan_start%02x\r\n",count);if (count == 0){scan_start();err_code = ble_advertising_start(BLE_ADV_MODE_FAST);APP_ERROR_CHECK(err_code);}
}

在这里面,主要是开始扫描和广播开始,我们关注扫描函数

static void scan_start(void)
{ret_code_t err_code;(void) sd_ble_gap_scan_stop();err_code = sd_ble_gap_scan_start(&m_scan_params);// It is okay to ignore this error since we are stopping the scan anyway.if (err_code != NRF_ERROR_INVALID_STATE){APP_ERROR_CHECK(err_code);}
}

这个函数里面有一个结构体

static const ble_gap_scan_params_t m_scan_params =
{.active   = 1,.interval = SCAN_INTERVAL,.window   = SCAN_WINDOW,.timeout  = SCAN_TIMEOUT,#if (NRF_SD_BLE_API_VERSION == 2).selective   = 0,.p_whitelist = NULL,#endif#if (NRF_SD_BLE_API_VERSION == 3).use_whitelist = 0,#endif
};

我在这里就不细说了,直接截屏网上的一段资料给大家

6、发送函数,是定义一个软件定时,10ms触发一次回调函数

这样就可以打开RTT,把主从程序下载进去,查看一下数据就行了,条件可以,也可以仿真一下,数据发送与接收的对不对,我的测试是没有问题的。

更多推荐

NRF51822学习笔记之主从通信讲解,另外附加把UUID更改成蓝牙技术联盟的基本UUID

本文发布于:2024-03-14 03:42:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1735550.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:主从   学习笔记   蓝牙技术   通信   联盟

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!