蓝牙开发笔记(BlueTooth,BLE,CH592)

最近在开发集成蓝牙模块的MCU,选来选去选择了CH592。之前用的是MCU+蓝牙透传芯片来做。

RISC-V内核BLE5.4 MCU/SoC CH592 - 南京沁恒微电子股份有限公司

CH592系列沁恒蓝牙产品-淘宝网

MounRiver Studio

WCHISPTool_Setup.exe - 南京沁恒微电子股份有限公司

官方链接下面有资料下载。

买了一块CH592EVT,下载好资料和安装集成开发环境(MounRiver Studio),下载工具WCHISPTool。

一、功能需求:

  • GPIO点灯
  • GPIO按键
  • 蓝牙通讯

二、GPIO部分:

三、蓝牙部分:

首先先看评估板说明说了解,资料包结构。PUB里面是资料,EXAM里面是源码。

打开:CH592EVT\EVT\PUB\CH592评估版说明书.pdf和CH592SCH.pdf

这里开发蓝牙使用的例程是:CH592EVT\EVT\EXAM\BLE\Central

3.1下载程序

说一下程序下载这部分,开始我是用MounRiver Studio编译和下载的,但是一直下不进去,后来看手册说用下载工具WCHISPTool下载。

我选择用USB下载方式下载,拿一个type-c转USB连接开发板和电脑。

3.2调试信息(串口)

type-c并不带串口的,需要自己准备一个USB TO TTL串口,PA8接TXD,PA9接RXD。

3.3修改程序

首先我需要根据从机蓝牙名称连接从机。

参考链接:蓝牙BLE主机Central讲解一(建立连接) - SweetTea_lllpc - 博客园

CH573 CH582 CH579蓝牙主机(Central)例程讲解一(主机工作流程) - WCH蓝牙应用分享 - 博客园

3.3.1 根据设备名称连接

了解上边这两个之后,改了根据设备名称连接

cpp 复制代码
static uint8_t* PeerDeviceName = "BSJ-FLIP-03";  //输入待连接的从机名称

在函数centralEventCB中
case GAP_DEVICE_INFO_EVENT:
{
     // Add device to list
     if((pbuf = strstr(pEvent->deviceInfo.pEvtData, PeerDeviceName)) != 0)//对比扫描到的名称
     {
         PRINT("pbuf = %s\n", pbuf);
         centralAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);
     }
    // centralAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);
}
break;

然后根据调试信息,观察主机工作流程。

3.3.2 发现根本没有服务的打印信息

在函数centralStartDiscovery里面

cpp 复制代码
uint8_t uuid[ATT_BT_UUID_SIZE] = {LO_UINT16(SIMPLEPROFILE_SERV_UUID),
                                  HI_UINT16(SIMPLEPROFILE_SERV_UUID)};

在gattprofile.h中宏定义
// Simple Profile Service UUID
#define SIMPLEPROFILE_SERV_UUID     0xFFE0

我的从机根本没有UUID为0xFFE0的服务。

我用手机BLE调试助手连了一下从机设备:

我在FFF1服务的上箭头,发送数据,从机可以接收到。那么就想办法让主机给FFF1的从机服务发送数据应该就行。

所以我改了:

cpp 复制代码
#define UNKNOWN_SERV_UUID           0xFFF0
#define UNKNOWN_SERV_RW_UUID        0xFFF1


uint8_t uuid[ATT_BT_UUID_SIZE] = {LO_UINT16(UNKNOWN_SERV_UUID),
                                  HI_UINT16(UNKNOWN_SERV_UUID)};

这回有服务信息了。

输出了"Write success"的信息,但是从机没有收到数据。

然后我怀疑是服务没有获取正确。CH592EVT蓝牙Central例程没有开启枚举服务 - 沁恒微电子社区

3.3.3 枚举从机所有服务

官方给了枚举从机所有服务的链接:

CH5xx 主机枚举从机所有服务 - WCH蓝牙应用分享 - 博客园

问了一下DeepSeek,不知道什么是服务、特征、描述符。

BLE的通用属性协议(GATT)的核心数据层次结构:设备 -> 服务 -> 特征 -> **描述符。**这是一个从大到小、层层包含的关系。

蓝牙BLE主机Central讲解三(服务枚举) - SweetTea_lllpc - 博客园

将central.c中两个函数全部替换。能够发送数据。

3.3.4 单字节写改为多字节写

在Central_ProcessEvent函数中if(events & START_READ_OR_WRITE_EVT),if(centralDoWrite)

里面

cpp 复制代码
原:

// Do a write
attWriteReq_t req;

req.cmd = FALSE;
req.sig = FALSE;
req.handle = centralCharHdl;
req.len = 1;
req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
if(req.pValue != NULL)
{
    *req.pValue = centralCharVal;
    if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
    {
        centralProcedureInProgress = TRUE;
        centralDoWrite = !centralDoWrite;
        tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT,DEFAULT_READ_OR_WRITE_DELAY);
    }
    else
    {
        GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
    }
}    

改为:
attPrepareWriteReq_t req;

req.handle = centralCharHdl;
req.offset = 0;  // 必须设置偏移量(从0开始)
req.len = sizeof(ModbusSeq);  // 数组长度
req.pValue = ModbusSeq;  // 指向整个数组

if(req.pValue != NULL)
{
    *req.pValue = ModbusSeq[0];
    if(GATT_WriteLongCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
    {
        centralProcedureInProgress = TRUE;
        centralDoWrite = !centralDoWrite;
        tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
    }
}
相关推荐
其美杰布-富贵-李2 小时前
tsai 中 Learner 机制深度学习笔记
人工智能·笔记·深度学习
wdfk_prog3 小时前
[Linux]学习笔记系列 -- [fs]dcache
linux·数据库·笔记·学习·ubuntu
小智RE0-走在路上3 小时前
Python学习笔记(7)--集合,字典,数据容器总结
笔记·python·学习
map_vis_3d4 小时前
JSAPIThree 加载单体三维模型学习笔记:SimpleModel 简易加载方式
笔记·学习·3d
Lv11770085 小时前
Visual Studio 中的密封类和静态类
ide·笔记·c#·visual studio
EniacCheng8 小时前
【RUST】学习笔记-整型
笔记·学习·rust
断剑zou天涯8 小时前
【算法笔记】树状数组IndexTree
java·笔记·算法
北岛寒沫8 小时前
北京大学国家发展研究院 经济学辅修 经济学原理课程笔记(第九课 公共产品与公共资源)
经验分享·笔记
Vizio<8 小时前
STM32HAL库开发笔记-STM32CubeMX点灯
笔记·stm32·嵌入式硬件