
1. 为什么选择杰里AC63做蓝牙耳机项目1.1 从一颗芯片说起AC63的定位与适用场景杰里AC63这颗芯片在国产蓝牙音频方案里算是一个比较有意思的存在。它属于杰理科技的中端蓝牙音频SoC系列主打的是低功耗立体声蓝牙音频场景内置了DSP指令集和专用的音频处理单元支持蓝牙5.1以上的协议栈常见于TWS耳机、头戴式蓝牙耳机、蓝牙音箱这类产品。我最早接触这颗芯片是因为一个客户要做一款入门级TWS预算卡得很死但又要求支持OTA升级和低延迟模式找了一圈最后落在AC63上。为什么选它而不是别家几个很现实的原因第一BOM成本低外围器件少一颗芯片加上少量阻容和晶振就能跑起来第二SDK成熟度够用杰理官方提供的fw-AC63_BT_SDK已经迭代到v2.4.0蓝牙协议栈、音频编解码、OTA框架都是现成的第三开发门槛相对友好虽然杰理的文档出了名的“惜字如金”但社区里踩过坑的人多遇到问题不至于完全抓瞎。这个项目适合谁看如果你是有一定嵌入式C基础、想入门蓝牙音频开发的工程师或者你手头正好有个小批量的蓝牙耳机项目要落地那这篇内容应该能帮你少走不少弯路。如果你完全是零基础建议先补一下C语言和基本的数字电路知识不然看SDK里的寄存器操作会比较痛苦。1.2 项目整体目标与技术路线这个项目的目标很明确基于fw-AC63_BT_SDK v2.4.0从零搭建一个可运行的蓝牙耳机固件工程最终实现蓝牙音频播放、按键控制、电量上报和OTA升级这几个核心功能。技术路线大致是这样的开发环境Windows下用杰理官方的IDE基于Eclipse定制配合专用的编译工具链。这里要注意杰理的编译链和标准的ARM GCC不太一样必须用官方提供的版本否则链接阶段会报一堆莫名其妙的错误。SDK结构fw-AC63_BT_SDK的目录结构比较清晰apps目录下放的是应用层代码include是头文件cpu是芯片相关的底层驱动lib是预编译的库文件。我们主要改的是apps/soundbox或者apps/spp_and_le这类示例工程。核心功能模块蓝牙协议栈BR/EDR BLE、音频编解码SBC/AAC、按键驱动、电源管理、OTA升级。调试手段串口打印是最主要的调试方式杰理的SDK里有一套自己的log系统通过配置log等级可以控制输出量。另外可以用蓝牙抓包工具配合分析协议交互。整个项目的难点不在于写多少代码而在于理解杰理SDK的框架逻辑。它的代码组织方式和常见的开源蓝牙协议栈比如Zephyr、BlueZ差别很大很多地方是“约定大于配置”你得先顺着它的思路走才能改得动。2. 开发环境搭建与SDK工程导入2.1 工具链安装别用错版本杰理AC63的开发环境搭建是第一个坑。官方推荐的是Windows 10 64位系统IDE用的是他们定制的Eclipse版本编译器是杰理自己的pi32v2工具链。我试过用标准的ARM GCC去编译结果在链接阶段报了一堆符号找不到的错误因为杰理的库文件是用他们自己的编译器生成的ABI不兼容。安装步骤大致如下从杰理官方渠道获取IDE安装包和工具链压缩包。注意不同SDK版本对应的IDE版本可能不一样v2.4.0的SDK最好配官方推荐的IDE版本别自己乱升级。安装IDE到默认路径路径里不要有中文和空格这是很多嵌入式工具的通病杰理的也不例外。解压工具链到指定目录然后在IDE里配置编译器路径。具体是在Window - Preferences - C/C - Build - Settings里把pi32v2-elf-gcc的路径指过去。安装串口驱动。AC63的调试串口用的是CH340或者CP2102这类USB转串口芯片驱动装好之后在设备管理器里能看到对应的COM口。注意安装路径千万不要带中文我见过有人把IDE装在“D:\开发工具\杰理”下面结果编译的时候各种文件找不到排查了半天才发现是路径编码问题。2.2 SDK目录结构解读与工程导入fw-AC63_BT_SDK v2.4.0解压之后目录结构大概是这样的fw-AC63_BT_SDK/ ├── apps/ # 应用层代码各种示例工程 │ ├── soundbox/ # 音箱类应用 │ ├── spp_and_le/ # 蓝牙串口BLE应用 │ └── ... ├── include/ # 公共头文件 ├── cpu/ # 芯片底层驱动 │ └── br63/ # AC63对应的CPU目录 ├── lib/ # 预编译库文件 ├── tools/ # 各种工具包括打包、OTA生成等 └── ...导入工程的时候在IDE里选择File - Import - Existing Projects into Workspace然后指向apps/soundbox目录。导入之后先别急着编译检查一下工程的编译配置Include路径确认include、cpu/br63、apps/soundbox/include这些路径都加进去了。链接脚本AC63的链接脚本在cpu/br63/tools/下面后缀是.ld确认工程引用的路径正确。宏定义SDK里有很多条件编译的宏比如CONFIG_OTA_ENABLE、CONFIG_BT_TWS_ENABLE这些宏决定了哪些功能会被编译进去。第一次编译建议先用默认配置跑通了再改。编译成功后在apps/soundbox/Output/目录下会生成.bin或者.ufw文件这就是可以烧录到芯片里的固件。2.3 烧录与首次上电验证烧录工具用的是杰理官方的下载器通过USB或者串口连接目标板。AC63支持多种烧录模式最常用的是串口烧录和USB烧录。串口烧录速度慢但接线简单USB烧录快但需要芯片进入特定的下载模式。烧录步骤把目标板通过USB转串口工具连接到电脑确认COM口。打开杰理的下载工具选择对应的芯片型号AC63加载编译生成的固件文件。给目标板上电同时让芯片进入下载模式通常是按住某个按键再上电具体看硬件设计。点击下载等待进度条走完。首次上电之后如果串口有log输出说明固件跑起来了。默认的log波特率一般是115200在SDK的board_config.h里可以改。如果串口没输出先检查晶振有没有起振再检查电源电压是否在芯片的工作范围内AC63一般是3.0V到4.2V。3. 蓝牙音频功能的核心配置与代码实现3.1 蓝牙协议栈初始化与设备名修改AC63的蓝牙协议栈初始化是在SDK启动流程里自动完成的但有几个关键参数需要我们在应用层配置。最基础的是设备名称和蓝牙地址。设备名称的修改在apps/soundbox/board/br63/board_config.h里找到BT_NAME这个宏改成你想要的名字。注意蓝牙设备名的长度有限制BR/EDR模式下最长248字节但实际使用中建议控制在20字节以内不然有些手机搜索的时候显示不全。蓝牙地址的配置稍微麻烦一点。AC63的蓝牙地址可以烧录到芯片的OTP区域也可以在代码里动态设置。如果是在开发阶段建议用动态设置的方式方便调试// 在蓝牙初始化之前调用 u8 local_addr[6] {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; bt_set_local_addr(local_addr);提示量产的时候一定要用OTP烧录唯一的蓝牙地址不然所有设备地址一样用户配对的时候会乱套。蓝牙协议栈的初始化流程大致是先初始化底层HCI再注册各种回调函数最后启动广播或者进入可连接状态。SDK里已经封装好了我们只需要在bt_init()之后注册自己的回调就行。3.2 音频编解码配置SBC还是AACAC63支持SBC和AAC两种蓝牙音频编解码格式。SBC是蓝牙音频的强制格式所有蓝牙设备都支持AAC音质更好但需要手机端也支持。在SDK里配置编解码格式是在bt_audio_config结构体里设置的static const struct bt_audio_config audio_cfg { .codec_type BT_AUDIO_CODEC_AAC, // 或者 BT_AUDIO_CODEC_SBC .sample_rate 44100, .bit_rate 320000, };实测下来AAC在同样的码率下音质确实比SBC好一截但延迟会稍微高一点。如果是做TWS耳机建议优先用AAC因为现在大部分手机都支持。如果是对延迟敏感的场景比如打游戏可以切回SBC延迟能低个20ms左右。音频通路的配置还包括采样率、声道数、音量曲线这些。AC63的DAC支持16bit和24bit输出采样率支持8k到96k。一般蓝牙音频用44.1k或者48k就够了再高意义不大反而增加功耗。3.3 按键与LED驱动的实现按键和LED是蓝牙耳机最基本的交互方式。AC63的SDK里有一套按键管理框架支持短按、长按、双击、多击等事件。配置按键需要在board_config.h里定义按键的GPIO和对应的功能// 按键配置示例 const struct key_config key_cfg[] { { .gpio IO_PORTA_01, .active_level 0, // 低电平有效 .long_press_time 1500, // 长按1.5秒 .click_cnt 1, // 单击 .callback key_click_handler, }, // ... };按键回调函数里处理具体的逻辑比如单击播放/暂停双击下一曲长按开机/关机。这里有个坑按键消抖。硬件上一般会加RC滤波但软件上也要做消抖处理不然会出现一次按下触发多次事件的情况。SDK里默认的消抖时间是20ms如果硬件滤波做得不好可以适当加大。LED的控制就简单多了直接操作GPIO就行。不过建议用一个独立的定时器来管理LED闪烁不要在按键回调里直接延时那样会阻塞其他任务。4. OTA升级功能的集成与调试4.1 OTA升级的原理与SDK支持OTA升级是蓝牙耳机的一个重要功能用户可以通过手机APP给耳机推送新固件不用拆机就能更新。AC63的SDK里已经集成了OTA框架支持后台式OTA和双区OTA两种模式。后台式OTA的原理是耳机在正常工作的同时通过BLE接收新固件数据存到外部的SPI Flash里等数据接收完了再重启切换到新固件。这种模式的好处是升级过程中耳机还能正常使用缺点是需要的Flash空间比较大至少要能存下两份固件。双区OTA则是把Flash分成两个区一个区跑当前固件另一个区存新固件升级的时候直接往备用区写写完了切换启动区。这种方式更可靠但Flash空间要求更高。在SDK里启用OTA功能需要在board_config.h里打开对应的宏#define CONFIG_OTA_ENABLE 1 #define CONFIG_OTA_TYPE OTA_TYPE_BACKGROUND #define CONFIG_OTA_FLASH_ADDR 0x100000 // OTA数据存储的Flash地址4.2 OTA固件包的生成与签名OTA升级用的固件包不是普通的.bin文件需要用杰理提供的工具进行打包和签名。工具在tools/ota/目录下一般是一个叫ota_pack_tool.exe的可执行文件。打包步骤先编译生成普通的固件文件.bin。用OTA打包工具加载这个.bin文件设置版本号、固件大小、校验方式等参数。工具会生成一个.ufw文件这就是可以用于OTA升级的固件包。把.ufw文件放到手机APP能访问的服务器上或者直接通过BLE传输。注意OTA固件包一定要做签名校验不然别人伪造一个固件包就能刷进你的耳机里。杰理的SDK支持RSA签名在打包工具里配置好私钥就行。4.3 OTA升级流程的调试与问题排查OTA升级的调试是整个项目里最折腾的部分。我遇到过的典型问题包括升级到一半断开多半是BLE连接参数没配好导致传输过程中连接超时。解决办法是把BLE的连接间隔调小比如从30ms调到15ms同时增大从设备的延迟容忍度。升级完成后无法启动检查新固件的启动地址和中断向量表是否正确。AC63的固件启动地址一般是0x0但OTA之后可能会变需要在链接脚本里配置好。升级速度慢BLE的传输速率有限如果固件包有几百KB升级可能要几分钟。可以优化传输协议比如增大MTU、启用数据长度扩展DLE能把速度提升一倍左右。排查OTA问题的时候串口log是最有用的工具。SDK里OTA模块的log等级可以单独设置建议调试阶段把OTA相关的log全打开能看到每一步的详细状态。5. 常见问题与实操避坑指南5.1 编译与烧录阶段的典型问题问题一编译报错“undefined reference to xxx”这个多半是库文件没链接对。检查工程的链接配置确认lib/目录下的.a文件都加进去了。另外杰理的库文件分好几种有libbt.a、libaudio.a、libota.a缺一不可。问题二烧录成功但芯片不运行先量一下晶振有没有起振AC63一般用24MHz的晶振。如果晶振没问题检查复位电路看看复位引脚是不是一直被拉低。还有一种可能是Flash里的固件校验失败芯片自动进入了ROM模式这时候串口会有特定的log输出。问题三串口log乱码波特率不对。AC63的默认log波特率是115200但有些工程会改成921600。在board_config.h里搜UART_BAUDRATE就能找到。5.2 蓝牙连接与音频播放的疑难杂症问题手机搜不到耳机先确认耳机的蓝牙地址有没有设置如果地址是全0或者全F有些手机会过滤掉。再检查广播参数广播间隔太长的话手机扫描的时候可能错过。建议广播间隔设置在100ms以内。问题连接后没有声音检查音频通路的配置确认DAC有没有使能音量是不是被静音了。另外有些手机在连接后会默认走HFP通话通道而不是A2DP音乐通道需要在代码里主动切换到A2DP。问题音频断断续续多半是射频干扰或者天线匹配没做好。AC63的射频输出是差分信号PCB走线要严格按照50欧姆阻抗控制。如果天线是PCB板载的注意净空区不要铺铜。软件上可以试着调整蓝牙的发射功率在bt_config里改tx_power参数。5.3 低功耗设计与续航优化蓝牙耳机的续航是用户最关心的指标之一。AC63支持多种低功耗模式包括sniff模式、hold模式和deep sleep模式。在不需要播放音乐的时候让芯片进入sniff模式能把功耗降到几毫安。具体的优化手段动态调整CPU频率播放音乐的时候跑高频率空闲的时候降频。关闭不用的外设比如LED、未使用的GPIO都配置成低功耗状态。优化广播参数广播间隔越大功耗越低但连接速度会变慢。一般设置在100ms到500ms之间比较平衡。电池管理AC63内置了电池电量检测功能可以定期读取电池电压通过BLE上报给手机。实测下来一颗300mAh的电池在正常使用每天听歌2小时的情况下续航能做到5天左右。如果一直播放音乐大概能撑8到10个小时。6. 项目扩展与后续优化方向6.1 增加TWS双耳互联功能AC63支持TWS真无线立体声功能两颗芯片之间通过私有协议通信实现左右耳同步。启用TWS需要在SDK里打开CONFIG_BT_TWS_ENABLE宏然后配置主从角色和通信参数。TWS的调试比单耳复杂得多主要难点在于同步。左右耳的音频播放必须严格同步不然会有回声或者声道错乱。SDK里有一套同步机制通过调整播放缓冲区的深度来补偿传输延迟。实测下来同步误差能控制在1ms以内人耳基本听不出来。6.2 接入手机APP进行参数配置通过BLE可以暴露一些自定义的服务和特征值让手机APP能读取和修改耳机的参数比如EQ设置、按键功能自定义、固件版本查询等。AC63的SDK里有一套BLE服务框架添加自定义服务需要定义UUID和对应的读写回调。这里有个小技巧把常用的配置项做成一个结构体通过BLE一次性读写比一个一个特征值读写效率高得多。结构体的大小控制在128字节以内这样一次BLE传输就能搞定。6.3 量产测试与固件版本管理量产阶段需要考虑的是测试效率和版本管理。杰理提供了一套量产测试工具可以自动化测试蓝牙连接、音频播放、按键、LED等功能。测试脚本可以用Python写通过串口控制测试夹具。固件版本管理建议用Git每个版本打一个tag记录对应的SDK版本和修改内容。OTA升级的时候版本号一定要严格递增不然手机会认为不需要升级。我个人在实际操作中的体会是杰里AC63这个平台上手不难但想做好做精需要花时间啃SDK。它的文档确实不够详细很多细节要靠看代码和试错来摸索。不过一旦跑通了整个流程后面做类似项目就能复用大部分代码效率会高很多。最后再分享一个小技巧调试蓝牙问题的时候用手机端的蓝牙抓包APP比如nRF Connect配合串口log一起看能快速定位是协议栈的问题还是应用层的问题。