蓝牙开发笔记(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);
    }
}
相关推荐
成都蜀味缘餐饮技术培训学校14 分钟前
手撕烤兔技术培训实战指南,秘制腌料配方比例与调制手法
大数据·经验分享·笔记·其他·微信公众平台
希和20271 小时前
免费AI视频生成工具汇总(国内优先,适合做漫剧、短视频,Obsidian笔记版)
人工智能·笔记·音视频
蒸蒸yyyyzwd3 小时前
秋招学习笔记 day109
笔记·八股
只愿云淡风清5 小时前
正则表达式学习笔记 02:基础语法
笔记·学习·正则表达式
希和202716 小时前
考研英语阅读词汇笔记|城市野径、抄近道步道(非正式小路)
笔记·考研
一个人旅程~18 小时前
关于imac27inch因改短用户名导致混合硬盘和系统崩溃的问题分析与故障解决
经验分享·笔记·macos·新浪微博
心祭丫丫19 小时前
【每天一个 Python 小案例17】Python 实现通讯录
开发语言·人工智能·笔记·python·学习
派大猩猩_21 小时前
Obsidian 笔记怎么同步多端:Nutstore Sync 大笔记库同步测评
笔记·obsidian·obsidian插件·obsidian同步
叼烟扛炮1 天前
Linux 学习笔记(五十):网络层——IP 协议、子网划分与 NAT 魔法
linux·笔记·学习
叼烟扛炮1 天前
Linux 学习笔记(六十):单线程的逆袭——epoll 高并发服务器实战
linux·服务器·网络·笔记·学习·算法