☰
杰理63系列主从连接与透传实战:从配置到排坑
2026/10/2 1:34:57 网站建设 项目流程

上周一个做蓝牙小家电的兄弟半夜发消息问我,手头有两块杰理63系列的开发板,想做一个主从连接,一块板子采集传感器数据往另一块传,结果照着文档折腾了两天就是连不上。我太理解这种状态了——杰理的SDK资料版本多、命名乱,官方文档又经常写得像给内部人看的,真正碰到主从连接和透传,踩坑的点一个比一个隐蔽。这篇文章就把我从选型、配置到跑通数据收发、再到排查问题的完整过程写下来,给后面做杰理63系列(AC692x、AC695x这几个常用型号)双设备主从透传的兄弟当个参考,帮你少熬两个通宵。

1. 上手前先想清楚:63系列的"主从"到底有哪些玩法

1.1 这个系列芯片的定位

杰理63系列在市面上最常见的几颗料是AC6925A、AC6926A、AC6928A(蓝牙4.2双模),以及AC6955A、AC6956A、AC69568这颗(蓝牙5.1双模)。不同型号在内核、Flash、RAM和协议栈版本上差别不小,但主从连接和透传的应用思路是贯通的。做产品选型时,如果只做低功耗数据采集,优先选BLE资源友好的型号;如果还要兼顾音频(A2DP/HFP),就必须上双模芯片,AC6928A就经常被拿来做"蓝牙伴音+数据透传",一个片子同时干两件事。

很多刚接触的人以为杰理只能做蓝牙音箱和耳机,其实它的串口透传方案在工控、医疗小设备、玩具遥控、数据采集模块里出货量非常大。原因很简单:成本够低、外围电路简单、SDK虽然文档乱但该有的API都有。主从双设备传输数据,本质上就是把两颗芯片分别配成"主机"和"从机",然后通过标准蓝牙协议把数据从一端搬到另一端。

1.2 别把"主从连接"和TWS搞混

这里必须先纠正一个最常见的误解:很多人把"主从"和"TWS左右耳互联"混为一谈。TWS是两颗同型号芯片用私有2.4G互联同步播放音频,走的是杰理内部的TWS私有协议,不是标准蓝牙。而我们说的"双设备主从连接传输数据",是标准的蓝牙主从关系——一台设备做Central(主机、中心设备),负责扫描和发起连接;另一台做Peripheral(从机、外设),负责广播并等待连接。数据通过SPP或BLE GATT通道传输,和手机连接一个蓝牙模块的原理完全一样。

这样区分清楚之后,你的整体设计思路就不会跑偏:不需要研究TWS配对那套私有命令,只需要按照标准蓝牙协议栈的节奏来,配置角色、配置服务、处理回调、收发数据。

1.3 主从玩法取决于你要传什么

同样是主从连接,传输的数据类型决定了你走哪条链路:

  • 传感器状态类:数据量小、频率低(几十到几百字节一跳),用BLE GATT的Notify就够,省电是第一优先级。
  • 串口透传类:要模拟有线UART做双向数据通路,不定长、连续、吞吐要求高,用SPP最省事,丢包和延迟都好控制。
  • 音频+数据混合:必须走经典蓝牙连接,SPP承载数据,A2DP承载音频,这种场景下芯片选型就要主动往双模高配置上靠。

所以,动手配置之前,先把"传什么、多大包、多频繁、功耗要求、要不要同时出声"这几个问题写下来,后面每一步配置都有了依据,不会反复推翻重来。

2. 数据走哪条链路:SPP与BLE的取舍

2.1 经典蓝牙SPP适合的场景

SPP对应经典蓝牙的RFCOMM层,从使用者的视角看,它就是一根"无线串口线"。在杰理SDK里打开SPP选项之后,从机对外暴露一个标准蓝牙串口服务,主机侧无论是手机还是另一块杰理板子,连接成功之后就能像读写串口一样收发数据。

SPP有几个特点很关键。第一,它要求配对绑定,连接的时候会触发配对流程,默认PIN码一般是1234或0000,这个在板级配置里能改;第二,它建立连接之后是长时间占用的,功耗比BLE高一个量级,不太适合纽扣电池方案;第三,它的吞吐和稳定性在同等条件下比BLE更好,我用AC6928A实测,SPP单向传输稳定在20~60KB/s之间,延迟大约10~30ms,这取决于UART波特率、协议栈缓冲区大小和连接质量。如果做的是"蓝牙转串口"这种模块类产品,SPP是首选。

2.2 BLE GATT适合的场景

BLE走的是GATT服务模型,你需要自定义一个Service,服务里面放Write、Notify、Read三种Characteristic。主机发给从机用Write,从机主动上报用Notify,主机主动拉取用Read。杰理SDK里默认会有一个自定义服务,初学阶段建议直接用官方Demo里的UUID,把服务跑通了再改成业务专用UUID。

BLE的优点是功耗低、连接参数灵活、支持广播和扫描的高效发现机制;代价是单包长度短、throughput没有想象中高。默认MTU只有23字节,刨掉ATT头实际有效载荷更少,需要协商MTU才能传稍大的包。我实测在7.5ms连接间隔下,BLE GATT的稳定吞吐在8~15KB/s之间,对传感器数据、控制指令这类"小包高频"业务完全够用,但别指望用它推文件。

2.3 一主一从、一主多从和连接表

主从拓扑上我建议按下面这个原则选:

  • 一主一从:最简单,两边资源压力都小,适合大多数透传场景。
  • 一主二从:一个主机维护两条连接,两条连接都处于活跃状态,主机的内存开销明显上升,老型号AC692x系列会比较吃力,AC695x系列相对从容。
  • 双主机连一个从机:从机要同时被两个中心设备连接,这要求协议栈支持多连接和合理的调度,老款63系列基本不用想,新一点的型号也要实测内存占用。

连接表这个概念很多人忽略。芯片能同时保持几条蓝牙连接,是协议栈在编译时就分配好的,不是想连几台就连几台。配置工具里如果没找到连接数目的选项,那多半是SDK写死的,改代码前先去翻协议栈配置头文件里的宏定义。

对比项SPPBLE GATT
底层通道经典蓝牙RFCOMM低功耗蓝牙ATT/GATT
功耗较高低
传输速率实测约20~60KB/s约8~15KB/s
延迟10~30ms连接间隔相关,通常20ms内
连接前是否配对需要可选
承载数据特点不定长、连续、大流量小包、低频、状态类
典型场景串口透传模块传感器上报、遥控

3. 工程配置实操:从SDK到协议栈开关

3.1 SDK目录里需要关心的几个地方

拿到杰理官方的SDK(AC692x或AC695x)之后,不要一上来就全局搜索代码,先认目录。以我常用的SDK版本为例,主要关心四块:

  • apps/:应用层代码,我们的业务逻辑基本都写在这里。
  • include/:协议栈对外暴露的头文件,想找API先来这儿搜。
  • board/:板级配置,涉及引脚复用、时钟、外设初始化。
  • tool/:烧录和调试工具,以及一些PC端小软件。

很多问题其实是"配置没生效"而不是"代码写错了"。杰理这套代码的配置分散在好几个地方:板级头文件里是引脚和资源,应用头文件里是功能开关,工具生成的文件里是蓝牙协议栈参数。改一处而不同步其他位置,就会出现编译能过但行为不对的诡异现象。

3.2 用配置工具生成板级配置

杰理官方提供蓝牙配置工具(不同SDK版本里的名字不太一样,常见的是蓝牙配置工具或BT Setting Tool),它的作用是生成一份协议栈参数文件,编译时会合并进固件里。需要重点确认的配置项有这几个:

  • 蓝牙名称:从机的广播名,调试阶段建议改成有辨识度的名字,避免和周围设备混淆。
  • Profile开关:勾选SPP、BLE,或者SPP+BLE同时开。
  • BLE服务的Service UUID和Characteristic UUID:先用官方默认值,后面再改成产品自定义的。
  • 主机角色是否开启:注意,不是所有SDK版本都默认开放Central角色,有些版本需要额外的宏或配置项。
  • 配对方式、PIN码、安全等级:SPP场景下一般选"Just Works"或固定PIN。

配置完成后生成文件,替换进工程对应位置,然后重新编译烧录。这步很多新手容易漏——改了工具不生成、生成了不替换、替换了不重新编译,最后来问"为什么没变化"。建议每次改完配置都确认生成文件的修改时间,确保真的更新了。

3.3 主从角色相关的宏开关

以我接触过的SDK版本为例,应用配置里会看到类似下面这些宏:

#define CONFIG_BT_SPP_ENABLE 1 // 打开SPP #define CONFIG_BT_BLE_ENABLE 1 // 打开BLE #define CONFIG_BT_MASTER_ENABLE 1 // 打开主机角色 #define CONFIG_BT_SLAVE_ENABLE 1 // 打开从机角色

这里面有一个非常关键的注意点:同时打开主机和从机角色,协议栈占用的RAM会比单角色多出一大截。老型号AC692x系列Flash和RAM本来就紧张,主从同时开之后编出来的固件很容易超资源,表现就是链接时报告内存溢出或者编译报错。我见过有人为了"一主一从"硬上双角色,结果是程序跑起来不稳定、连接后随机死机。如果只是双设备互传,建议一台刷主机版本、一台刷从机版本,双方宏定义不同,烧录不同的固件,这样资源压力最小,问题也最好定位。

编译烧录之后,先用手机上的蓝牙调试工具(nRF Connect或LightBlue都行)验证从机:能搜到广播、能连上、能看到服务列表和Characteristic。这一步能快速过滤掉一大半"配置没生效"的问题。手机验证通过了再上双设备联调,否则两边都是黑盒,出了问题根本不知道是谁的错。

3.4 烧录验证与串口日志

杰理的下载工具通过UART或USB接口下载固件,烧录前确认板子的BOOT引脚状态正确,不要用错串口,这个环节最常见的错误是下载工具报"连接失败",十有八九是BOOT模式没进对。下载完成后,开启SDK的打印日志功能,把协议栈事件打出来,连接、断连、收发数据都会有日志输出。这条日志会贯穿整个调试过程,是排查问题最重要的信息来源。

4. 代码层面实现主从连接与数据收发

4.1 从机端的初始化与事件处理

从机代码的核心是"广播 + 事件回调"。初始化阶段设置广播参数、注册回调,之后的事都由协议栈事件驱动。

以我用的SDK版本为参考,从机初始化大致是这样:

// 从机初始化 void app_ble_slave_init(void) { // 设置广播参数:设备名称、广播间隔、广播内容 // 打开广播 // 注册连接/断连/数据接收回调 }

事件回调里重点处理三个事件:连接成功、断连、收到数据。

static void ble_slave_event(u16 opcode, u8 *buf, u16 len) { switch (opcode) { case BLE_SLAVE_CONNECTED: // 连接成功,此时可以关闭广播省电,也准备好收发缓冲 break; case BLE_SLAVE_DISCONNECTED: // 断线了,重新打开广播,进入可被发现状态 break; case BLE_SLAVE_RECIVE_DATA: // 主机下发数据,buf为数据指针,len为长度 handle_rx_data(buf, len); break; } }

这里有个经验:收到数据之后,不要在回调里直接做耗时的处理(比如写Flash、开文件、长时间循环),回调函数是跑在协议栈上下文里的,占用太久会导致蓝牙协议栈喂狗不及时或丢包。正确做法是拷到自己的缓冲区,交给应用任务去处理。

4.2 主机端的扫描、连接和服务发现

主机端代码比从机多一个"找设备"的阶段。流程是:开启扫描、扫描回调里匹配目标设备名或MAC地址、停止扫描、发起连接、连接成功后做服务发现、找到Notify特征后订阅通知。

void app_ble_master_start_scan(void) { // 开启扫描,设置扫描窗口和扫描间隔 // 扫描结果在回调里处理,匹配到目标设备后停止扫描并发起连接 }

服务发现是很多新手容易卡住的地方。BLE的GATT服务不是连接建立就自动暴露给主机的,主机必须显式地遍历从机的Service、Characteristic、Descriptor,找到自己关心的UUID,然后才能收发数据。这一步如果没做,后面调用发送接口一定会失败或没反应。建议在日志里把发现到的服务和Characteristic UUID全部打印出来,确认和从机配置工具里设置的一致。

4.3 数据收发的完整闭环与实际接口

把收发接口按用途封装一下,业务层就好写了。从机向上发数据:

// BLE Notify方式发送,单包不要超过MTU-3字节 ble_slave_send_data(buf, len); // 如果是SPP通道 spp_send_data(buf, len);

主机向下发数据:

// 往已连接的从机写数据 app_ble_client_write(conn_handle, buf, len);

主机订阅从机的Notify之后,从机调用的发送接口会触发主机的接收回调,数据在回调里同样拷贝出来。

实际项目里最常见的形态是做"UART透传桥":MCU的串口收到数据,转发到蓝牙通道发出去;蓝牙通道收到的数据,从串口发出去。这种桥接逻辑很好写,但要注意缓冲区设计——串口的速率可能比蓝牙通道快,如果你在串口中断里直接调用蓝牙发送接口,数据量一大就会出现发送失败,原因是协议栈内部缓冲满了。我建议维护一个环形缓冲区:串口中断只往环形缓冲区里塞数据,应用层定期取出并调用蓝牙发送接口。

// 伪代码:串口数据进环形缓冲,应用层发蓝牙 void uart_rx_isr(u8 byte) { ring_buf_push(&tx_ring, byte); } void app_task_loop(void) { u8 tmp[128]; u16 len = ring_buf_pop(&tx_ring, tmp, sizeof(tmp)); if (len > 0) { ble_slave_send_data(tmp, len); } }

这个"缓冲+任务发"的模式能避免绝大多数丢包和发送失败问题,不管是SPP还是BLE都适用。

5. 实测参数与排坑记录

5.1 我实测的吞吐和延迟

不同SDK版本、不同连接参数,实测数据差异不小,但可以给你一个参考范围。我在AC6928A双板主从SPP透传场景下测试,UART波特率115200,单向连续发送,稳定吞吐约45KB/s,基本跑满了SPP的上限。换成BLE GATT、连接间隔7.5ms、MTU协商到247字节,单向吞吐大约12KB/s。延迟方面,SPP从发出到对端接收约15ms左右,BLE大约在10~20ms之间浮动。如果你测出来的数值比这个低很多,先检查是不是UART波特率配错了,或者发送端是不是一包一包等确认,这会让实际速率大打折扣。

5.2 排查问题要按链路走,别瞎试

我把自己经常遇到的几个问题和排查顺序整理成下面这个表,遇到问题先按链路一层层查,效率比随机改参数高得多。

现象排查链路常见根因
主机扫描不到从机广播开关→广播名→广播间隔→MAC过滤→硬件天线从机没开广播、配置工具没重新生成、天线匹配差
连接后几秒就断配对流程→安全等级→连接超时参数→看门狗配对未完成、交互超时太短、回调里耗时操作
能连上但收不到数据MTU协商→Notify订阅→UUID匹配→缓冲区主机没有订阅Notify、服务UUID不一致
发送接口返回失败连接句柄→协议栈发送缓冲→单包长度连接还没建立就发数据、单包超MTU
一拖二连第二个就掉线连接表数量→剩余RAM→扫描是否停止内存不足、连接参数配置过于激进

这里面有几个特别容易被忽略的坑。第一个是蓝牙天线匹配,我在调试时遇到过两次"扫描不到设备",最后发现是板载天线焊盘虚焊,信号强度太低,手机能搜到但另一块杰理板子搜不到,因为板载天线的灵敏度本身就不高。这种情况用仪器测一下RSSI就明白了。第二个是配对缓存,如果从机里存了旧的主机Link Key,主机换了设备或重刷固件后连接会异常,解决办法是把从机的配对信息清掉,或者在做开发调试时直接关闭绑定存储。

5.3 几条能省下大把时间的经验

最后分享几条我反复用到的实操经验。

第一,先把两端固件都编译成"手机可调试"的模式。从机用手机连,主机也用手机模拟连接。两边分别通了,再把两块板子放在一起联调,这样每个环节出问题都清楚是哪端的事。

第二,SDK里自带的Demo一定要先原样烧录跑通,再改你的业务逻辑。很多问题是你改代码引入的,不是配置问题。跑通官方Demo之后再逐步加自己的代码,出错了也容易二分定位。

第三,所有配置文件和生成的代码,记得纳入版本管理,并在发布前用对比工具确认当前工程用的参数和你以为的一致。杰理的SDK版本更新频繁,网上找到的教程和你的SDK很可能对不上,函数名、宏定义、配置工具界面都不一样,不要照搬硬抄。以你自己SDK包里的Demo为准,把API名字查清楚再动手。

第四,调试透传功能时,建议先跑一个固定格式的心跳包或计数值程序,比如从机每秒向主机发一次递增数据,主机串口打印出来。这样链路是否通、延迟是否正常一眼就能看出来,比上来就传真实业务数据好定位得多。链路通了再挂真实业务,问题范围一下就能缩小。

这块内容我后续还会接着整理杰理BLE配网、OTA升级和低功耗唤醒的实测记录,等新板子到了继续填坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询