1. 为什么选CH592:一颗RISC-V蓝牙MCU的定位与功力
1.1 CH592在蓝牙MCU市场里的位置
做蓝牙产品的硬件工程师,选型时最纠结的往往不是“哪个芯片性能最强”,而是“哪个芯片能让我少踩坑、快量产、成本还压得住”。CH592这颗芯片,严格来说不是用来追最新蓝牙规格的,它解决的是“常规蓝牙产品”里那些最折磨人的问题:功耗能不能做到纽扣电池跑一两年、协议栈稳不稳定、SDK好不好上手、外围电路能不能精简到极致。
CH592来自沁恒,基于RISC-V内核,集成了2.4GHz射频收发器、BLE协议栈和一堆常用外设。跟早期的CH579相比,CH592的内核换了、射频部分重新做了、低功耗模式也打磨得更细。如果你之前做过CH579,上手CH592会明显感觉到:同样的低功耗需求,现在能用更少的代码和更简单的外围实现。它不像ESP32那样动不动就几百毫安的峰值功耗,也不像nRF52那样连开发环境都要折腾老半天,CH592的定位非常明确:低功耗、低成本、快量产。根据公开资料和实际使用经验,这颗芯片挺适合TWS耳机充盒管理、BLE键盘鼠标、遥控器、传感器节点、智能家居小面板一类产品。
选型时,很多人会拿CH592和杰理、炬芯那些做蓝牙音频的SoC比,其实两者根本不是一个赛道。杰理这些方案把蓝牙音频编解码、DSP算法、存储全塞进一颗芯片里,适合做音箱、耳机这种完整音频产品;但如果你的产品是“带蓝牙的数据采集或控制设备”,核心任务是跑协议栈、处理传感器、控制外设、把功耗压到微安级,那么CH592这种“MCU+BLE”的单芯片才是更合适的答案。
1.2 集成方案的整体框架:单芯片不只是少一颗芯片
所谓集成方案,往小了说就是画一块板子,往大了说其实是“在天线、电源、协议栈、应用层、产测”这几个维度上一并收敛。CH592单芯片方案最大的优势,是把BLE协议栈和MCU放在一起,省掉了原来很多产品“MCU + 蓝牙模块”的架构里那一堆麻烦:串口AT指令交互、应答超时、模块固件升级、板间干扰、合作开发时协议扯皮。
我做过用HC-05那类经典蓝牙模块的老项目,当年在串口上一条条AT指令去配置模块、对波特率、调试连接超时的经历,现在回头看,真的是一把辛酸泪。HC-05这类模块调试时最典型的问题是“模块连接不上”,原因往往就是TX/RX接反、波特率不对、配对模式没进对,每个问题都得用串口工具去试。而CH592这类方案,协议栈在内部,代码能直接操作GATT服务、广播包、连接参数,所有通信行为都是可编程、可调试的,不会出现“模块莫名失联只能断电重启”的玄学问题。
从产品角度来说,集成方案要拆成四个层面来看:硬件上,电源、射频匹配、天线、时钟;协议上,广播参数、连接参数、GATT服务设计;低功耗上,睡眠划分、唤醒源、事件调度;产测上,射频校准、天线匹配的批量一致性。下面我从这四个层面,把我实际跑过的流程和踩过的坑都展开讲讲。
2. 集成方案的硬件设计关键:电源、射频、时钟与外设规划
2.1 电源设计:低功耗的起点是供电架构,不是软件
很多人在低功耗设计上有个误区,以为代码里调一调睡眠模式就行,其实硬件的供电架构决定了功耗的下限。CH592内部有LDO和DC-DC两种供电路径,从数据手册和实测经验来看,用DC-DC模式在发射和接收时效率更高,代价是外围要加一个电感和电容;用LDO模式外围很简单,但高电流场景下损耗会大一些。如果你做的是纽扣电池供电产品,我强烈建议把DC-DC的通路留出来,哪怕初期贴的是LDO,PCB上也要预留电感位置,方便后期改。
电源设计上还有几个容易被忽视的点:
- 去耦电容要靠近电源引脚放,一般是0.1uF配1uF或10uF的组合,电容离引脚超过3mm,效果就大打折扣。
- 电池供电时,注意低ESR的MLCC在电压跌落时产生的纹波,如果射频发射瞬间电流突然拉高,电源跌落会直接导致发射功率下降或者重启。
- 如果产品里还有电机、振动马达这类负载,必须在电源入口做隔离,否则马达启动瞬间的电压跌落会让蓝牙断连。我做过一个振动反馈手环,一开始马达和MCU共用一路电源,每次马达一开蓝牙就掉,后来加了RC隔离和续流二极管,才彻底解决。
这里做一个基于常见实践的补充:理想情况下,BLE系统的供电轨目标纹波控制在50mV以内,尤其在PA发射开启的瞬间。你可以用示波器在射频发射时抓电源电压波形,如果能看到明显的跌落尖峰,那就说明储能电容不够或者布局走线过细。
2.2 射频设计与天线匹配:距离短、功耗高,十有八九是这里
射频这块是CH592方案集成时最容易翻车的环节。芯片本身引出来的RFIO引脚需要一个匹配网络,再连到天线。最常见的是π型匹配网络,三个焊盘位,一个串电感或0欧电阻,两个并联位悬空或贴电容,用于量产时微调阻抗。
PCB天线设计有几个硬指标:天线下方要净空,不能铺铜;天线周围的器件要远离,尤其不能有大的金属件和GND走线贴着天线绕;天线匹配网络的器件要放在天线馈点附近。很多时候“蓝牙连不上”、“距离只有几米”,根本不是芯片问题,而是天线净空被破坏或者匹配没调。用网络分析仪看回波损耗是最可靠的方式,如果条件有限,也可以靠改并联电容值,观察实际通信距离的峰值变化来粗调。
外置天线的话,注意馈线长度和走线阻抗,IPEX座子的地要就近打过孔到主地,信号线的阻抗控制到50欧左右。具体阻抗计算可以用常见的叠层计算工具,但最终一定要靠板厂的阻抗报告确认。
2.3 时钟设计:一颗不准的晶振会让功耗“莫名其妙”变高
CH592需要外部晶振提供RF时钟,一般主晶振是32MHz左右,还需要一颗32.768kHz的RTC晶振用于低速时钟。高频晶振的精度直接影响BLE的信道频率偏移,如果晶振偏差太大,接收灵敏度会下降,导致双方不断重传,看起来就是“功耗突然变高”“连接不稳定”。我实际遇到过一批板子,广播距离一会远一会近,最后查出来是晶振负载电容匹配不对,换成数据手册推荐的负载电容值就好了。
32.768kHz晶振的功耗也非常关键。低速晶振在睡眠时一直跑,如果选的晶振本身ESR高或者起振电路配置不对,睡眠电流可能从1uA涨到5uA。对于一颗设计上要跑两三年的纽扣电池产品,这4uA的差距就是一年少三个月的寿命。布局上,两颗晶振要靠近对应引脚,走线短,两侧包地,避免数字信号耦合过来。
2.4 外设接口与引脚规划:做硬件设计时就要想好软件的事
引脚规划看似简单,但直接影响后续的低功耗调试。我的习惯是:可唤醒的GPIO尽量分配到有外部中断的引脚上,而且每个唤醒引脚都要明确上下拉状态。比如按键唤醒,外部用上拉电阻到VCC,平时按键悬空是高电平,按下拉低触发唤醒;这个上拉电阻的漏电也要算进休眠电流里,10k上拉在3V下就是0.3uA的漏电,如果你用了四五个按键,加起来就不是小数目了。
串口、I2C、SPI这些接口,设计时要考虑到调试和量产测试。我通常会把UART0留出来做日志输出和产测指令口,哪怕产品量产时不用这个口,开发阶段也能省大量事。SWD烧录口必须引出来,不要只留测试点,最好是排针或邮票孔形式,方便产线夹具压接。
另外,CH592带有USB、ADC、PWM等外设,如果你的产品需要USB充电或者采集模拟量,选型时可以一并评估。注意USB引脚和RF天线要拉开距离,否则USB高速翻转信号会干扰射频接收。这点在Type-C接口的便携产品上特别明显。
3. 低功耗设计的核心:睡眠策略、事件规划与功耗测算
3.1 芯片的低功耗模式与功耗量级
CH592这类BLE MCU,低功耗设计的关键不是“哪个模式电流最低”,而是“在什么场景下用哪个模式,以及如何快速进出这个模式”。常见的模式有:
- 正常运行模式:CPU工作,外设开启,电流在毫安级甚至更高。
- 睡眠模式:CPU停,低速时钟保持,RTC可唤醒,RAM数据保持。这个模式是BLE产品的常态,电流在微安级。
- 掉电或深度睡眠模式:保留极少资源,唤醒后要重新初始化系统,电流可以降到非常低。
根据公开资料与典型BLE MCU的实测经验,可以给一组参考量级:运行模式峰值电流在10mA上下,发射瞬间会更高一些;睡眠模式大概在1~10uA;深度睡眠可能低于1uA。不同固件配置差别很大,实际以你手上的芯片数据手册和实测为准。
把功耗模型建立起来,比盯着某个瞬时电流更重要。你的产品一天内可能有十个小时在深度睡眠、十四个小时在浅睡眠加定时唤醒、偶尔几十秒在运行。按时间加权计算的平均电流,才决定了电池寿命。
3.2 蓝牙协议栈对功耗的“隐藏控制权”
低功耗设计里,工程师对协议栈的控制往往决定成败,而不是CPU频率或GPIO上下拉。BLE的空闲状态靠的是“广播-扫描-连接”的事件模型:广播时芯片在几个信道上发广播包,然后立刻回去睡觉;连接后设备在约定的事件时间醒来收包发包,其余时间继续睡。
因此,广播间隔和连接间隔就是功耗的分母。广播间隔从20ms调到1000ms,平均电流可以相差近一个数量级;连接间隔从30ms调到100ms,功耗也大幅下降。代价是设备被发现变慢、数据收发延迟变大。选择参数时要在应用场景和功耗之间找平衡。比如产品只需要定时上报温湿度,那连接建立后可以把连接间隔拉到100ms以上,甚至用从机延迟把有效监听频率降得更低;如果是低延迟遥控器或自拍器,连接间隔就要控制在20ms左右。
MTU大小也会影响功耗。MTU是BLE一次数据包能承载的最大有效载荷,默认一般只有23字节,其中还包含协议头,实际用户数据很小。如果传输较大数据块,MTU不调大,就要分成很多包发,每一包都有协议开销。做数据传输类产品时,连接建立后第一件事就是协商MTU,通常可以协商到247字节甚至更高。数据吞吐上,MTU从默认值提升到200字节以上,同样传1KB数据,空中时间可能缩短一半以上,反应到功耗上是非常明显的。
3.3 典型场景功耗估算与电池寿命计算
这里给出一个基于常见实践的功耗估算表,具体数值需要拿自己的板子实测校准:
| 场景 | 平均电流参考值 | 说明 |
|---|---|---|
| 深度睡眠(RTC保持) | 1uA量级 | 视电路漏电、上下拉电阻而定 |
| 睡眠+GPIO唤醒 | 2~5uA | 包含外部上拉漏电 |
| 浅睡眠+定时唤醒 | 10~30uA | 唤醒周期越短,电流越高 |
| 广播(间隔100ms) | 50~150uA | 取决于发射功率与包长 |
| 广播(间隔1000ms) | 10~30uA | 适合可被发现但不频繁交互的场景 |
| 连接(间隔30ms) | 200~500uA | 数据交互频繁,功耗大头 |
| 连接(间隔100ms) | 50~150uA | 适合低频率数据同步 |
| 运行+外设操作 | 1~10mA | 取决于外设类型和CPU频率 |
算电池寿命时,别直接把容量除以平均电流。电池还有自放电、低温容量衰减、电压跌落造成的提前截止。以CR2032纽扣电池为例,标称容量大概220mAh,但如果你用平均电流做到100uA,理论上220mAh/0.1mA = 2200小时,约三个月;实际上还要打折。如果目标是半年以上,平均电流必须做到20uA以下。
我看到很多低功耗产品翻车,都是“一算寿命很乐观,一实测全傻眼”。原因就是实际产品里不可能全程都在深度睡眠,总有定时唤醒、LED闪烁、传感器采集、蓝牙连接交互。靠谱的做法是直接做一张“一天场景时间表”,比如一天唤醒10次采集并广播、每次运行50ms、其余深度睡眠,算出一个加权平均电流,再用实测功耗曲线去修正。
3.4 测量功耗的姿势:万用表串联是“入门”,示波器才是“真相”
调试低功耗时,我最怕看到有人拿万用表直接串联测休眠电流。万用表测电流有分流电阻,在uA级档位上的压降可能超过芯片的工作电压范围,导致芯片唤醒时供不上电、反复复位、电流比正常值高一截。更麻烦的是,万用表的采样率很低,芯片瞬间唤醒的毫安级脉冲根本捕捉不到,读出来的数字是平均后的假象。
我常用的方法是:静态电流用高精度万用表在uA档或专门的电流表测量,动态功耗用示波器配合电流探头或低功耗专用的电流测量工具,抓取一个完整工作周期(从睡眠到唤醒执行任务再回睡眠)的电流波形。如果手头没有电流探头,可以串一个极小的采样电阻,用示波器差分测电阻两端电压换算电流。很多低功耗问题,比如“为什么我的睡眠电流有30uA”,一抓波形就知道是定时唤醒太频繁还是GPIO漏电,用万用表反而会一直在那里瞎猜。
4. 协议栈集成与常见应用场景拆解
4.1 从SDK到广播跑通:一个最小工程的开发流程
CH592的开发流程,其实和主流BLE MCU差不多:下载官方SDK,创建工程,配置GATT服务。官方SDK里通常已经带了完善的例程,包括BLE外设广播、从机、主机、OTA等。我的建议是,不要自己从零开始搭工程,直接在现有例程上改。
一个最小代码逻辑,伪代码如下:
// 初始化BLE协议栈 BLE_Init(); // 设置设备名称和广播数据 uint8_t adv_data[] = {0x02, 0x01, 0x06, 0x03, 0x03, 0x01, 0x18}; BLE_SetAdvData(adv_data, sizeof(adv_data)); // 启动广播,间隔100ms BLE_StartAdvertising(100); // 主循环处理事件 while(1) { BLE_Task(); // 应用层逻辑 }当然这只是示意,实际CH592 SDK里API名称会有差异,具体参考官方例程。这里想说的是一个思路:BLE应用本质上是个事件循环,广播、连接、发送、接收都是事件,你把自己的业务逻辑插在对应事件回调里就行。不需要关心底层分帧重传,协议栈帮你处理了。
4.2 连接参数协商:一次连接到底能传多少数据
连接建立后,两端要协商一组连接参数,包括连接间隔、从机延迟、监控超时。连接间隔是两次连接事件之间的时间。从机延迟的意思是,当从机没有数据要发时,可以跳过若干个连接事件继续睡觉,这会大幅降低功耗。代价是主机往从机发数据时,如果从机在跳过连接事件,数据就要等从机醒来才能收,实时性会变差。
我之前调试一个BLE数据采集器,需要把传感器数据以20ms一次的频率实时传出来。一开始按照例程默认的7.5ms连接间隔跑,功耗高得吓人;后来改成连接间隔15ms,再从机侧做数据缓冲,把多个采样点合并成一包,功耗立即降了一半以上。这说明,连接参数不能照抄例程,要根据你自己的数据量和实时性要求设计。
MTU协商同样关键。默认MTU只有23字节,扣除协议头,用户数据只有20字节,传真实数据非常低效。连接建立后,双方可以交换MTU请求,把单包数据长度提到几十甚至200字节以上。如果你做的是OTA升级、日志传输这类功能,MTU不协商到位,升级时间可以差好几倍。在CH592上,协议栈一般提供了MTU交换接口,应用层主动发起,不加代码的话它会一直维持默认值。
数据吞吐量还受连接间隔限制。BLE 4.2之后单包可以到251字节,估算吞吐时可以简单算:连接间隔内实际能传的包数受限于每个连接事件的最大包数和间隔时长。大体上看更大的MTU和更短的连接间隔可以提升吞吐,但同时增加功耗。
4.3 HID设备集成:键盘、遥控器、自拍器
输入类设备是BLE应用中的大头,也是CH592的强项。BLE HID设备要在GATT服务里定义HID服务,包含报告映射、输入报告、输出报告等特征。协议栈会封装大部分HID逻辑,你需要做的事情核心是设计报告描述符。
报告描述符决定了你的设备在PC和手机上呈现成什么类型。自拍器通常是定制的报告格式,而键盘鼠标这类标准设备要遵循一定规范。注意配对后主机会记住设备,如果你的报告描述符改了,主机端可能还按旧描述符解析,出现“连上了但是按键乱码”的情况。改协议时把主机端的配对记录删掉再测。
另外,HID键盘类设备有个细节:主机上如果没配对成功,设备是不能直接进系统使用的。BLE协议栈需要支持固定配对和动态配对,CH592一般是通过配对密钥和输入输出能力来管理。部分主机会拒绝无安全认证的HID设备,所以HID产品出厂时的配对流程要设计清楚。
4.4 广播与扫描参数调优
广播参数直接在协议栈API里设置。广播间隔越大,被发现的概率越低,功耗也越低。如果你的产品需要“靠近即发现”“按键后立刻可连接”,广播间隔要短一些;如果只是定时上报,把广播间隔拉到几百毫秒甚至一秒都行。
广播信道数量也值得关注。BLE在三个信道上发送广播包,默认是都开的。如果你发现某个信道被Wi-Fi或别的蓝牙设备干扰严重,可以屏蔽那个信道,代价是设备发现的概率降低。一般开发阶段还是保持三个信道全开,量产时根据实际环境再调。
扫描参数是接收端的配置。扫描窗口越短、扫描间隔越长,扫描机越省电,但发现设备越慢。做“手机扫描到设备”这个场景时,常见的问题是广播间隔太长导致手机半天搜不到,调试时可以先用短间隔(比如20ms)把功能跑通,再慢慢往上加间隔测功耗,找平衡点。
5. 开发调试中的典型问题与排查思路
5.1 搜不到设备、连接不稳定
这是我被问得最多的一类问题。搜不到设备的排查顺序,我建议按这个来:
先确认芯片有没有在正常广播。用手机装一个通用的BLE调试工具,看能不能看到设备名或广播数据。看不到,先检查供电和复位,看晶振有没有起振,代码有没有跑到广播启动的位置。如果芯片跑飞了或者晶振没起振,代码层面怎么查都查不出来。
排除软件因素后,再考虑RF问题。广播数据里带上一个递增的包序号,每次发送加一,用抓包工具查看是否连续;如果乱序严重,说明空中环境在重传,可能是天线匹配差或信道干扰。天线净空不足、匹配元器件错贴,是最常见的硬件问题。
连接后频繁断开,除了距离问题,还要看监控超时参数。连接事件里连接间隔太长,而监控超时设得太短,设备稍微忙一点没来得及收包,主机就判定连接丢失了。协议栈的默认参数一般没问题,但如果应用层在某个操作里长时间占用了协议栈处理,比如写Flash期间CPU停了RTOS调度,就会出现此类问题。
5.2 实测功耗偏高,从哪排查
实测功耗偏高的排查,千万别直接在代码里猜,按数据说话。先测静态电流和动态波形,然后用排除法:
第一,把外设逐个关掉。传感器、LED、上拉电阻、电平转换芯片,这些都可能贡献漏电。有些传感器休眠电流几十微安,已经超过了MCU本身的休眠电流,不用的时候软件上要把它们的电源切掉。第二,检查GPIO状态。未配置的GPIO悬空,会通过内部上拉或下拉形成通路漏电,最稳妥的方式是把所有不用引脚配置成高阻输入或指定电平。第三,看唤醒频率。用示波器数一数每秒唤醒多少次,很多“30uA”都是因为定时器频繁触发。
一个容易被忽略的点是,蓝牙的收发事件在代码里看起来是“没运行的”,但其实协议栈一直在周期性地醒来监听。连接状态下,从机必须在每个连接事件醒来收包,哪怕没有数据。这就是为什么连接间隔越长越省电。如果产品不需要一直在连接状态,直接主动断开连接,再回到广播或睡眠,可能更省电。
5.3 深睡唤醒后异常复位、数据丢失
深度睡眠唤醒后,相当于“从零开始”初始化系统,RAM内容可能保留也可能不保留,取决于模式和芯片设计。有些芯片支持保留RAM的睡眠,有些会丢失,你需要把关键参数存到非易失区或备份寄存器里。我遇到过一次唤醒后设备反复复位的问题,排查了半天,是因为唤醒源引脚没有做去抖处理,上电后引脚电平抖动了几次,触发了多次唤醒中断,系统一直启动到一半又被拉回睡眠。
解决办法是加RC滤波或在代码里做软件去抖:唤醒后先读引脚状态,确认稳定了再执行初始化。这类问题在实体按键产品里特别常见,开关本身的机械抖动在唤醒瞬间非常明显。
5.4 数据丢包与重传机制
BLE协议栈有链路层的重传机制,但BLE链路层重传是有限次的。如果空中干扰严重,重传失败就会断开连接或上报错误。做数据传输产品时,应用层要有自己的确认机制,不能完全依赖BLE链路层的可靠传输。我的习惯是设计应用层协议时加一个简单的序号位和CRC校验,接收方收到后回确认帧,发送方超时未确认才重传。对于低成本、低功耗产品来说,这种轻量机制足够,比引入TCP/IP这类重量级方案划算得多。
如果你做的是OTA升级,这个应用层确认机制更重要。升级中断在BLE产品里非常常见,没有断点续传或完整包校验,设备可能升级失败变砖。CH592的SDK一般带有OTA方案,但建议提前规划好Bootloader和App的分区结构,给OTA之外留一条安全的回退路径。OTA升级时建议把连接间隔缩短、关闭其他业务任务,降低空中丢包的概率。
5.5 关于复杂场景的一些经验提示
蓝牙音频场景里,A2DP和SCO模式切换是很多工程师绕不过去的坎。这里也顺便提一下:BLE MCU本身不处理音频流,如果你做的是通话降噪、音乐播放这类产品,需要的是蓝牙音频SoC而不是CH592这类通用BLE MCU。在设计初期就要想清楚产品属于哪一类,是“蓝牙透传/控制设备”还是“蓝牙音频设备”,这两种技术路线完全不同。如果拿BLE MCU硬扛音频流,大概率会在开发中后期发现射频带宽、内存、实时性都跟不上。
做定位或测距类应用时,广播包和连接包的时间戳精度很关键。BLE测距主要依赖RSSI或多径特征,CH592这类通用BLE MCU可以做一些初步的RSSI测距,但精度受环境影响较大,室内定位往往还需要配合其他传感器做融合。
最后说几句实在话
我做低功耗蓝牙产品的体会是,选对芯片只是第一步,后续的低功耗设计才是拉开差距的地方。CH592这套方案,硬件上花心思把电源、天线、时钟这些基础做好,软件上把睡眠策略和蓝牙参数按实际场景一点点调,最终产品才能既稳定又省电。栽过那么多跟头之后,我现在每次画板之前都会先把“一天内的功耗时间表”算清楚,把唤醒源和GPIO状态理清楚,再动手写代码。这个习惯救了我很多次,也分享给你。做这行最大的快乐,大概就是看着自己设计的设备在电池供电下安安静静地跑上几个月,那种踏实感是很踏实的成就感。