【Win32】【蓝牙】跨平台实现Ble Master&Slave&Mesh 之Windows篇

一,背景

1,基于Window开发蓝牙的需求较为迫切,且需要基于Windows的蓝牙能力应用于生产,工控设备控制以及设备交互等。
2,基于Windows开发蓝牙存在很多弊端以及门槛,相对于上位机开发工程师而言,嵌入式软件工程师长期与蓝牙设备开发打交道,对蓝牙较为熟悉,所以衍生出来通过嵌入式开发底层接口,上位机开发UI等实现方式。

二、设计思路

1,模型框图

模型

2,具体设计

硬件设计方案来自:Nordic52832

设计框图

三、具体代码分析

如上设计,具体代码分为三部分:设备端固件、Windows PC Host驱动库、Windows应用逻辑(对上为库)

1,设备端固件

设备采用的是:Nordic52832小板,裸模块+串口CH340串口
参考设备驱动固件源码为NRF SDK15.3 + 适配PATCH(nRF5_SDK_15.3.0_connectivity.patch)
SDK源码可在官网获取,这里附上PATCH地址:https://github.com/NordicSemiconductor/pc-ble-driver/tree/master/hex

1.1,本地RAM设定

RAM设定
由于需要打一部分log,把设备端应用程序的ram拉大了,这里如果非调式阶段,可以把应用程序RAM设定小一点,尽可能把RAMA给协议栈使用。(例如:RAM_START=0x2000ab20;RAM_SIZE=0x54e0)

1.2,源码分析

中间层映射表:
中间层映射表

这里仅仅需关心使用的那部分,毕竟接口太多,感兴趣可以深入了解。

1.3,编译固件
1. Apply PATCH:
git apply nRF5_SDK_15.3.0_connectivity.patch --ignore-whitespace

2. Compile the \nRF5_SDK_15.3.0_59ac345\examples\connectivity\ble_connectivity\pca10040\ser_s132v3_hci\ with armgcc or ses — NRF52832 DK

编译结果:(这里做了ram分配,协议栈可使用更大)
编译

2,Windows PC Host驱动库
2.1 涉及源码部分

之所以用Microsoft Visual Studio,便于可视化编译Windows依赖库以及避免繁琐的脚本工具安装。

大致源码如下:
代码框架

注:这里需要注意添加宏定义,否则编译会过不了。

// 宏定义:
NRF_SD_BLE_API_VERSION=6
_CRT_SECURE_NO_WARNINGS
ASIO_STANDALONE
SD_RPC_EXPORTS
HCI_LINK_CONTROL
_WIN32_WINNT=0x0501

如果编译部分存在疑惑可在我的资源部分下载,放到pc-ble-driver源码中+重新添加你所需的头文件地址即可。

2.2 部分源码分析

设定COM口以及波特率:
在这里插入图片描述

底层用C++实现逻辑,具体编解码部分没啥深入意义,不做详述。
这里需要注意一个关键点:open rpc module的时候需要注册ble事件,类似于添加一个observer,当前可添加一个,如需多个observer,需自定义在函数内控制。(可控)

在这里插入图片描述

3,Windows应用逻辑(向上为静态库,属协议部分)

目前可提供ble slave以及ble master多设备控制,slave较为简单,我们以ble master深入应用

3.1 初始化注意事项

这里需要注意一个非常关键的点:设定最大对端设备数量,否则无法多设备连接以及控制。

在这里插入图片描述

// 设定最大对端设备连接数量由BLE_CONN_CFG_GAP控制  
// 设定最大对端设备GATT PDU由BLE_CONN_CFG_GATT控制
// 注:这里的ram start是虚的,没意义

    memset(&ble_cfg, 0x00, sizeof(ble_cfg));
    ble_cfg.conn_cfg.conn_cfg_tag                       = conn_cfg_tag;
    ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count     = MAX_PEER_COUNT;  // 4
    ble_cfg.conn_cfg.params.gap_conn_cfg.event_length   = BLE_GAP_EVENT_LENGTH_DEFAULT;

    error_code = sd_ble_cfg_set(ble_port_adapter, BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
    if (error_code != NRF_SUCCESS)
    {
        printf("sd_ble_cfg_set() failed when attempting to set BLE_CONN_CFG_GAP. Error code: 0x%02X\n", error_code);
        return error_code;
    }

    memset(&ble_cfg, 0x00, sizeof(ble_cfg));
    ble_cfg.conn_cfg.conn_cfg_tag                 = conn_cfg_tag;
    ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = 247; // This is CFG_GATT configuration

    error_code = sd_ble_cfg_set(ble_port_adapter, BLE_CONN_CFG_GATT, &ble_cfg, ram_start);
    if (error_code != NRF_SUCCESS)
    {
        printf("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATT.",
                      error_code);
    }

3.2 扫描注意事项

如果需要接收扫描scan response,需要使能对应扫描标志,否则你接收的到永远都是adv data,没有rsp data:
rsp enable

同时注意接收端判定adv or rsp的标志:
flag

3.2 设备连接注意事项

由于这里会对不同service uuid的设备进行连接,故每次连接成功后我们需要检索对应uuid:
discovery service

同样的获取对应特征值的handle也需要多次判断:
在这里插入图片描述

最后便是cccd handle了,一个service下对应一个,这个没必要多次检索了
在这里插入图片描述

3.4 设备透传
    if(ble_conn_state_status(m_tuya_ble_c[i].conn_handle) != BLE_CONN_STATUS_CONNECTED) {
        printf("Current Device status: %d\n", ble_conn_state_status(m_ble_c[i].conn_handle));
        return -2;
    }

    ble_gattc_write_params_t write_params;

    write_params.handle     = m_tuya_ble_c[i].tuya_tx_handle;
    write_params.len        = data_len;
    write_params.p_value    = p_data;
    write_params.write_op   = BLE_GATT_OP_WRITE_CMD;
    write_params.flags      = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
    write_params.offset     = 0;

    err_code = sd_ble_gattc_write(ble_port_adapter, m_tuya_ble_c[i].conn_handle, &write_params);

四、实现效果

1, 验证扫描结果

scan

2, 连接多设备并透传

主动连接设备:
connect

数据发送以及接收:
send data

断开设备:
disconnect

3,补充:beacon发射:

beacon

phone

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tim-Cheng

你的鼓励是我最大的动力,奥利给

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值