前阵子一个做智能锁的朋友问我:产品不打算支持手机听歌,只求手机APP能通过蓝牙连上、下发几条指令,然后设备自己播报“已开锁”“电量低”这样的提示音,选哪颗国产芯片合适。他特别强调,市面上蓝牙音频芯片好多都是为听歌设计的,他觉得用不上那些功能,想找个“便宜又能跑BLE透传”的芯片。
这个问题听着简单,但落到硬件选型上,背后有一条很关键的技术分叉:“不要蓝牙音频”不代表“不需要音频链路”。你要的“本地语音播报”,本质上还是要让MCU能从Flash里把一段语音读出来、解码、经过功放推给喇叭,只是不需要从手机接收连续的音频流而已。这篇文章我就按这个需求,把国产BLE芯片和国产蓝牙音频SoC的选型逻辑、实测感受、容易翻车的细节一次说清楚。
1. 先拆需求:不要蓝牙音频,不等于不要音频链路
很多朋友一上来就瞄着蓝牙芯片去挑,想的是“把BLE透传跑通不就完事了”。但在这个项目里,真正决定选型难度和成本的,往往不是蓝牙那一端,而是“本地语音播报”这一端。
1.1 你说的“本地语音播报”到底是什么
本地语音播报的意思是:语音文件提前存在设备本地(片内Flash、外挂Flash、外挂语音芯片里),当某个事件发生(按键、PIR触发、BLE指令下发)时,设备自己播放对应提示音。它和蓝牙音频完全是两回事:
- 蓝牙听歌=A2DP流媒体,手机不断把音频数据包推给音箱/耳机,设备要实时解码、实时播放。
- BLE透传=GATT读写/通知,数据量很小,几字节到几百字节/包,适合控制指令、传感器数据。
- 本地语音播报=本地解码+本地播放,蓝牙只是触发条件之一。
所以你的芯片其实要做的事情是“MCU跑BLE协议栈 + MCU解码并播放语音”,而不是“MCU跑蓝牙音频协议栈”。这直接影响了芯片选型范围。
1.2 本地语音播报的三条物理实现路径
我见过的方案基本分三类:
- 音频SoC直接放:芯片自带DAC、音频解码器,甚至内置功放,比如杰理AC696x、中科蓝讯AB53xx、炬芯ATS2853。代码里把MP3/WAV文件的地址指给它,它自己解出来从DAC输出,你外面接一个小功放推喇叭就行。
- 普通BLE SoC用PWM模拟输出:芯片主频足够、定时器足够,就用PWM输出一个载波,对占空比进行调制,经过RC低通滤波还原音频波形。泰凌TLSR8258、奉加微PHY6252这类低功耗BLE芯片都能这么干,只是音质比较“广播调调”。
- BLE SoC外挂语音播报芯片:主控通过UART/SPI/IO直接触发一颗专用语音芯片(比如WT588F系列),语音芯片自己从Flash里读音频、自己解码、自己推喇叭。主控的负担最小,代价是多一颗芯片、多一个BOM位。
提示:这三条路径不冲突。你可以先用PWM播报做原型验证,后面量产为了降低MCU负载,再换成外挂语音芯片方案。选BLE SoC时只要保证它有足够定时器资源,这两个方案都能落脚。
2. 选型之前,先分清国产BLE/音频芯片的三种流派
国产芯片这几年在蓝牙这块卷得厉害,但“国产”两个字掩盖不了内部流派差异。你要选的是“BLE透传+本地语音播报”,得先知道自己站在哪条产品线上。
2.1 音频SoC流派:杰理、中科蓝讯、炬芯
这一类芯片本来是为了蓝牙耳机、蓝牙音箱设计的,双模甚至三模,主打音频链路成熟。它们普遍内置DAC、支持MP3/AAC/WAV硬解,也支持BLE GATT透传。你说不需要听歌,完全可以不开A2DP相关功能,只用BLE+本地语音这一小部分。
优点是语音体验最好,音质稳定,SDK对“提示音”这类需求通常有现成API。缺点是SDK封闭,杰理和蓝讯的资料基本都要NDA(保密协议),散兵游勇式的开发者很难入门;而且一颗音频SoC你只用了它20%的能力,成本上不见得比“BLE SoC+小语音芯片”便宜。
2.2 低功耗BLE SoC流派:泰凌、奉加微、国民技术
这一派的核心能力是BLE射频和低功耗,主打IoT透传、传感器、门锁、表计。它们本身不做音频解码,但片上外设够用,你可以用PWM、定时器、UART去“拼”一条语音输出链路出来。代表有泰凌TLSR8258、奉加微PHY6252、国民技术N32WB031。
优点是对“BLE透传为主、偶尔播报一句”的产品非常契合,待机功耗可以压到微安级,而且资料开放度普遍比音频SoC好。缺点是语音链路要自己搭,没有现成解码器,高音质播放就别想了。
2.3 通用WiFi/BLE SoC流派:乐鑫ESP32系列
严格说这是个跨界选手。ESP32-C3既有WiFi又有BLE,算力强、Flash大、I2S外设齐全,开发资料和社区活跃度国产芯片里数一数二。用I2S外接一个小DAC模块,播报音质可以做得比PWM好很多。
缺点是功耗偏大,不适合纽扣电池长期待机的产品;另外你只用到BLE+语音,把WiFi射频部分也集成了,芯片面积会大一些。做原型验证它是真香,做极致成本量产它不是最优。
| 流派 | 代表芯片 | 语音链路 | 低功耗 | 资料开放度 | 适合产品 |
|---|---|---|---|---|---|
| 音频SoC | 杰理AC696x、蓝讯AB53xx | 内置DAC/解码器 | 中等 | 低,需NDA | 门锁、音箱、词典笔 |
| 低功耗BLE SoC | 泰凌TLSR8258、PHY6252 | PWM/I2S/外挂语音芯片 | 优秀 | 中等偏上 | 表计、门锁、健康设备 |
| 通用WiFi/BLE | ESP32-C3 | I2S外接DAC/功放 | 一般 | 高 | 原型验证、联网设备 |
3. 几颗典型国产芯片的逐个实测印象
纸上谈兵没意思,聊聊我实际在项目里碰过的几颗芯片。不吹参数,而是说它们在“BLE透传+本地语音播报”这个场景下的真实手感。
3.1 泰凌TLSR8258:IoT老将,适合把它当“带射频的MCU”用
TLSR8258在这个圈子里太常见了,门锁、灯控、Mesh组网、智能家居网关内部小模块,到处能看到它。它是BLE 5.0 + 802.15.4多协议SoC,主频48MHz,Flash主流版本512KB,RAM也够用。对语音播报来说,它没有DAC和音频解码器,但官方SDK里外设驱动很全,PWM、定时器、DMA都能调。
我在一个“低功耗门磁语音提醒”的Demo里,就是用TLSR8258的PWM直接播ADPCM语音。把一段8kHz采样、4-bit ADPCM编码的“欢迎回家”存在Flash里,定时器中断喂数据,PWM载波设到125kHz左右,后面接一个RC低通滤掉载波,再进8002功放推喇叭。结果:语音能清楚听懂,带一点“打电话”的质感,但作为提示音完全够用。Flash占用每分钟语音大约240KB,512KB Flash放下几十条提示音没问题。
它的优点是你把它当“带BLE射频的MCU”来用,外设自己支配,非常自由。缺点也一样:音频链路全要自己搭,工程能力不足的人容易卡在音质和中断抢占上。另外泰凌有几个不同SDK分支,Mesh和BLE单独跑,选型时要把SDK版本对齐,别拿Mesh工程去改透传。
3.2 奉加微PHY6252:性价比和上手成本的平衡点
PHY6252这两年在低功耗BLE模组里出镜率很高,很多白牌模组厂都拿它做料,Pin兼容nRF52832,采购和资料都比较友好。用它做“BLE透传+本地语音”的思路和TLSR8258差不多,都是PWM模拟语音,或者用外挂语音芯片来降低主控负担。
让我印象比较深的是它的低功耗:广播待机做到几个微安级别不是问题,对做电池供电的智能锁、电子价签、健康手环这类产品非常友好。而且市面上成品模组多,天线匹配和认证这块能省不少事。语音方案上,我在一个电子秤项目里用过“PHY6252 + 外挂语音芯片”的组合,主控只管通过串口给语音芯片发播报指令,语音芯片自己解码自己播放,BLE连接几乎不受干扰,开发效率反而比用PWM硬写音频链路高。
3.3 杰理AC696x:语音体验最好,但SDK的坑也是真实的
杰理AC696x系列是典型的蓝牙音频SoC,双模蓝牙,支持BLE+经典蓝牙。它自带DAC,可以直接输出音频给功放,MP3/WAV都能硬解。我在朋友那边接触过用AC6963B做智能门锁的案子,门锁本地播报“已开锁”“电量低”“请更换电池”,BLE用来连APP做临时密码下发。说句公道话,语音声音干净、延迟低、代码量很少,体验确实比PWM方案强一大截。
但它的短板也很突出:SDK需要签NDA,网上公开资料少,个人开发者第一次玩会比较难受。而且杰理芯片的资料、烧录工具、量产测试工具基本都是为方案公司和整机厂服务的,你要么找代理要全套资料,要么直接让方案公司帮你开发。如果你公司有一定量级、有渠道绑原厂FAE,选它省心;如果只是几个人的小团队,我建议先别碰。
3.4 中科蓝讯AB53xx:和杰理类似,音频能力给得很足
中科蓝讯的AB53xx系列在TWS耳机上出货量很大,同样支持双模蓝牙,内置DAC。用在“BLE透传+本地播报”上也完全可以,思路和杰理基本一致。我个人的感受是,它的BLE透传部分做得很顺手,产品定义里如果是“既有手机App连蓝牙设置参数,又要本地语音反馈”的音频类硬件,它比低功耗BLE SoC方案更快出活。
不过也要提醒一句:蓝讯的芯片经常有不同型号对应不同耳机/音箱方案,命名很接近但资料不通用。选型号之前一定要找原厂或者代理确认,它是否开放BLE GATT透传API、本地提示音API怎么调用、Flash怎么烧录。我见过有人直接按某宝标题买芯片,结果买到的型号SDK对不上,白折腾一周。
3.5 乐鑫ESP32-C3:我原型验证时反而最爱用它
如果这个项目不要求极限低功耗,只是想把产品逻辑先跑通,我一般直接抓ESP32-C3模块。它的BLE 5.0协议栈成熟,ESP-IDF样例丰富,网上搜BLE UART透传一抓一大把,语音播报用I2S外接MAX98357A功放模块,3.3V供电直接推3W喇叭,硬件连接就是两行线,音频质量甩开PWM方案一个档次。
它的定位不是“低功耗BLE透传芯片”,所以别指望它做纽扣电池长期待机的产品。但当开发板、当验证工具、当小批量首发版本,它非常能打。很多产品可以先拿ESP32-C3验证完体验和交互,再决定要不要复制到低功耗量产的BLE SoC上。这也是一种很务实的选型策略。
4. 语音播报落地时最容易翻车的四个细节
芯片选好了,真正动手你会发现坑都在后面。下面这些是我踩过、也看别人踩过的点,基本每条都能省你一周时间。
4.1 音频素材格式和Flash预算必须提前算
本地语音最忌讳“先用高音质WAV跑通再说”。语音提示音不需要HiFi,8kHz采样率的窄带语音,人耳完全能听懂。我建议从源头就不要用16bit线性PCM直接存,优先用ADPCM压缩格式。
一个简单的预算公式:8kHz采样率,4-bit ADPCM,每秒音频=4KB,一分钟=240KB。如果你用16kHz采样,则翻倍到480KB/分钟。主流BLE SoC的Flash在512KB级别,放几十条短提示音完全够。如果语音量比较大,就外挂一颗SPI Flash,地址空间随便安排。
我用的工具链一般是:Audacity录音、降噪、切段,导出8kHz/16bit/mono WAV,再用泰凌SDK里自带的音频转换工具或者语音芯片厂商的转换工具,转成ADPCM的C数组或二进制,直接烧进Flash的独立分区。这一步不要在项目后期才做,因为语音分段方式会影响代码里的索引表设计。
注意:MP3/AAC这类压缩格式,没有硬解的话,普通BLE MCU解码会占用大量CPU和内存,得不偿失。除非你选了杰理/蓝讯这类带硬解的音频SoC。
4.2 PWM输出语音和DAC直出的差异,比你想象大
PWM播语音的原理是:用定时器产生一个高频PWM载波,占空比随音频采样值变化,然后通过一阶RC低通把高频分量滤掉,还原出音频包络。这里面有两个关键参数:PWM载波频率和低通截止频率。
PWM载波要尽可能高,至少比采样率大8~16倍。比如8kHz采样率,PWM频率我习惯设到100kHz以上,这样三阶RC之后残留载波比较小,不会有刺耳的“沙沙声”。低通截止频率取3~4kHz左右,正好保留语音能量最集中的频段,超出部分切掉。相位和阻抗也要考虑,RC的电阻取值会影响到DAC输出阻抗和末级功放输入阻抗,建议用二阶有源滤波或者直接照抄芯片厂商官网的参考电路。
相比之下,DAC直出方案(杰理/蓝讯那类)就没这么多调参问题。所以如果你的产品特别在意“声音干净”,尽量选DAC硬解方案;如果只是“能听清内容”,PWM方案完全能接受。
4.3 播报瞬间和BLE连接抢“时隙”是隐性炸弹
本地语音播报是实时任务,BLE协议栈也是实时任务,两者共用同一颗MCU时,出错方式往往是:语音正常播了,手机那边却一直连接断开、数据超时。
原因很简单:语音播放在定时器中断里频繁喂数据,占用了CPU;而BLE连接事件同样需要及时响应,一旦被语音中断拖住,手机就认为链路超时。我实测TLSR8258时遇到过,播放8kHz语音时,如果中断服务函数里做了太多事情,手机端的连接间隔就开始飘,严重时直接断开。
解决办法有几个方向:
- 用DMA或者双缓冲来搬运采样点,而不是在每个采样点中断里做大量解码工作。
- 解码一次填充一块buffer,再交给PWM/DMA自动输出,MCU只在buffer半空/全空时去读下一块。
- 调整蓝牙连接参数:把连接间隔适当拉长,或者利用空闲时间播放。
- 实在冲突严重,可以播放期间暂停BLE的复杂业务包,只保持最小连接维护。
我建议在第一版代码里就加入播放任务和BLE任务之间的优先级管理,别等测试挂了再补。
看一段思路示例:
#define ADPCM_BLOCK_SAMPLES 256 static uint8_t s_play_buf[2][ADPCM_BLOCK_SAMPLES]; static volatile bool s_play_switch_toggle = false; // 定时器中断/播放buffer半空中触发:填下一块数据 void audio_fill_next_block(void) { uint8_t *dst = s_play_buf[!s_play_switch_toggle]; adpcm_decode(dst, current_src_ptr); current_src_ptr += ADPCM_BLOCK_SAMPLES / 2; // 4-bit ADPCM每2采样=1字节 s_play_switch_toggle = !s_play_switch_toggle; } // 主循环里做,不要在中断里连续搬几十KB void ble_event_handling(void) { if (ble_event_pending) { ble_stack_process(); } }核心思路是:中断里只做“搬一块数据”,BLE处理放主循环或更高优先级回调,避免长时间互相卡死。
4.4 功放选型对射频的影响,容易被忽略
喇叭驱动需要功放,而功放是板上一个很大的干扰源。D类功放的输出是PWM开关波形,开关频率通常落在几百kHz到几MHz之间,谐波会通过供电、地环路、走线耦合到蓝牙天线,导致灵敏度下降、连接距离变短。
我的习惯是:
- 1W以内、语音清晰度要求不高的,用AB类功放比如8002系列,干扰更可控;代价是效率低一些,待机稍大。
- 需要效率优先的,用D类功放比如NS4150,板子上功放输出走线要尽量远离天线,电源之间加磁珠或者π型滤波。
- 功放的使能脚单独接GPIO,不播报时直接关断,既省电又减少干扰。
我做门锁项目时,第一版D类功放放在天线旁边,蓝牙距离短了差不多一半,后来把喇叭线拉远、功放底下铺了完整地平面并加了LC滤波才稳定下来。这个问题单看原理图很难发现,到了整机装配和拉距测试才会暴露,提前规避比事后救火省事得多。
5. 一套可以直接抄的Demo架构:BLE透传+ADPCM本地语音
理论说完,放一套我实际验证过的Demo架构,场景假设就是“智能锁/健康设备”这类典型产品:手机App通过BLE连设备,下发一条指令,设备播放对应语音,并且回一个状态。
5.1 硬件连接示意
我这个Demo用的是“低功耗BLE SoC + AB类功放 + 喇叭”的最小链路:
- BLE SoC引脚:PWM0输出音频,GPIO_A控制功放Enable。
- PWM经过一阶RC低通(10kΩ + 100nF,截止约160Hz?不对,10k+100nF是159Hz,太低,实际要根据音频带宽算。我一般用1kΩ+47nF,截止大约3.4kHz)再进功放。
- 功放输出接8Ω/1W喇叭。
- 语音数据用ADPCM编码,放在BLE SoC内部Flash或外挂Flash。
提示:截止频率=1/(2πRC),想算到3kHz,用1kΩ和47nF比较合适;具体器件值还要结合后级功放的输入阻抗做微调,不要照抄所有项目。
5.2 BLE Service怎么设计
透传部分不一定非要自己造协议,很多国产SDK都提供“Nordic UART Service(NUS)”风格的透传demo,一份service包含一个TX(notify)和一个RX(write)通道。我一般在此基础上加一个控制通道:
| Characteristic | 权限 | 作用 |
|---|---|---|
| 0xFF01 | Notify | 设备上报数据/状态 |
| 0xFF02 | Write | 接收APP指令,比如“播报第3条语音” |
| 0xFF03 | Read | 设备能力查询,比如固件版本、支持的语音列表 |
APP下发指令建议用二进制短帧,而不是裸字符串。比如一帧3字节:[帧头0xA5, 指令码0x01, 语音索引0x03]。这样解析简单、不容易误触发。播报完可以再从0xFF01 notify一个0xA5 0x02 0x00,表示“播报完成”,APP端可以做UI联动。
5.3 播放调度和低功耗怎么同时兼顾
ADPCM播放期间,MCU不能一直清醒着等所有采样点播完。更合理的方式是维护一个小队列:APP下发播报请求后,主控把要播放的语音索引写入播放队列,播放协程逐段解码填充PWM buffer。播放期间保持蓝牙连接,但减少不必要的数据交互;播完自动清队列、关闭功放电源、MCU进入轻度睡眠。
待机功耗这块,我实测下来能做到的指标大概是:保持BLE广播(非连接模式)待机电流8~15µA;建立连接后,如果连接间隔拉到100ms以上,平均电流几十微安;播报瞬间电流会到几十毫安,所以供电设计要按峰值预留,不是按平均电流选电池。功放不播报时一定要从硬件上关断,有些功放即使没输入也有静态电流,会拖累整机待机。
5.4 语音素材准备和固件打包
我习惯把语音素材在编译阶段就并入固件,而不是运行时从文件系统去读。具体是:把ADPCM的二进制文件用xxd -i或Python脚本转成C数组,放到一个独立的audio_data.c里,索引表维护一段结构:
typedef struct { const uint8_t *data; uint32_t len; } audio_clip_t; const audio_clip_t audio_table[] = { { welcome_adpcm, sizeof(welcome_adpcm) }, // 索引0:欢迎使用 { unlocked_adpcm, sizeof(unlocked_adpcm) }, // 索引1:已开锁 { low_power_adpcm, sizeof(low_power_adpcm) },// 索引2:电量低 };APP下发索引1,MCU就查表拿到“已开锁”这段ADPCM数据,解码播放。这样做的好处是:固件升级可以连带更新语音,不需要手机额外传输音频文件;语音和代码的耦合度也低,加一条语音只改表。
6. 按你的优先项直接选:一张决策表加我的真实倾向
说了这么多,最后给一个能让决策落地的总结,不绕弯子。
6.1 按功耗优先:只看低功耗BLE SoC
要纽扣电池撑一年,就不要碰音频SoC,乖乖走泰凌TLSR8258、奉加微PHY6252这类低功耗BLE SoC路线。语音用PWM加上仔细设计睡眠唤醒,整机待机做到微安级是现实目标。外挂语音芯片会多一份待机电流,但如果语音芯片本身支持休眠,也能接受。
6.2 按开发速度优先:先上ESP32-C3,别纠结
如果产品要在两周内出可演示原型,或者团队对BLE协议栈不熟,直接买ESP32-C3开发模块,用官方BLE UART透传例程加I2S功放,两天就能出声。后面再研究是否需要移植到低功耗芯片量产。
6.3 按语音体验优先:选音频SoC
如果客户听过一次“HiFi提示音”就回不去了,或者产品本来就要放MP3背景音、学习内容,那直接选杰理AC696x或中科蓝讯AB53xx,语音链路全是现成的,开发效率也不低。前提是你的团队有办法搞定SDK渠道NDA和技术支持。
6.4 一张表直接抄
| 你的最大诉求 | 推荐方向 | 理由 |
|---|---|---|
| 低功耗、长待机 | 泰凌TLSR8258 / 奉加微PHY6252 | BLE功耗低,语音链路自己控制 |
| 快速出原型、团队小 | ESP32-C3 | 资料全、生态好、I2S音质稳 |
| 语音好听、播报内容多 | 杰理AC696x / 蓝讯AB53xx | 内置解码器和DAC,音频体验最稳 |
| 不想自己写解码,量又大 | BLE SoC + 外挂语音芯片 | 主控简单,产线组装容易,语音芯片成本低 |
我个人的实际体会是,这类“BLE透传+本地语音播报”的项目,超过一半最后都会走“低功耗BLE SoC + PWM/外挂语音芯片”的路线,因为它的BOM成本可控、待机功耗漂亮、BLE连接又稳。真正需要音频SoC的场景,往往是语音本身成了产品主要卖点,而不仅仅是提示音。
最后分享一个小技巧:不管最终选哪颗芯片,第一版硬件都留出PWM和I2S两种语音输出接口,哪怕只是多两个测试点。原型阶段你可能觉得某个方案够用,等整机测试发现音质或者干扰问题时,有一条备用链路意味着不用重新打板。选芯片不是比谁参数最好,而是比谁更适合你的产品形态和团队能力,抓住这点,选型就不会跑偏。