做工业产品选型这些年,我最大的感受是:芯片的纸面资源越来越不重要,功耗和外围成本反而成了卡脖子的点。CH32L103这颗国产RISC-V工业MCU,主频96MHz,封装小到QFN28/TSSOP20,却把USB PD PHY、运放、比较器、触摸按键检测全塞了进去,低功耗表现也到了uA级别。对我来说它解决的是工业现场常见的“小封装、省外围、低功耗、还得够用”这类问题。这篇内容适合正在评估低功耗MCU选型的嵌入式工程师,也适合做电池供电设备、Type-C配件、便携仪表的硬件开发者参考。
1. 芯片定位与核心亮点:它不是又一颗Cortex-M0
1.1 RISC-V内核和96MHz主频:实时性到底够不够
CH32L103用的是沁恒自研的青稞V4C内核,属于RISC-V 32位指令集,支持IMAC组合,也就是整数乘法除法、原子操作都有。看到“RISC-V”很多人会担心生态不成熟,实际上这两年用下来,MounRiver Studio里点个编译、烧录、断点调试,流程和传统IDE没什么区别。
96MHz主频在这个级别里算比较能打的。很多工业现场任务,比如Modbus轮询、传感器采集、PWM输出,其实对绝对算力要求不高,对“中断来得够不够快、能不能在几微秒内完成上下文切换”反而敏感。青稞内核的硬件压栈机制在这里起了作用:中断现场由硬件自动压栈,响应速度比软件压栈快不少。我在一个编码器计数应用里实测,外部中断频率到几十kHz时,中断服务函数里只做标志位操作,CPU占用率依然很低。
另一个容易忽略的维度是代码迁移。CH32L103的外设库函数风格和ST早期标准外设库相似,GPIO_Init、ADC_Init这套写起来很顺。如果你是从STM32F103这类平台转过来的,看EVT例程基本没有陌生感。但注意,寄存器名字、位定义和ST不是一一对应,别指望直接把工程搬过来,重写一遍外设初始化是正常工作量。
1.2 内置运放、比较器和PD PHY:省掉了哪些外围
这颗芯片最让我心动的地方,不是主频,而是模拟资源和协议资源的集成度。
工业采集场景里最常见的是电流采样、温度采样、微弱信号放大。以前要么外挂一颗运放,要么用分立电阻搭差分放大,占板面积大不说,失调和温漂还难控制。CH32L103内部集成了运放,可以直接做信号跟随或者放大,输出送给内部ADC。板子上少一颗运放,BOM成本降一点,故障点也少一个。
比较器也是工业场景里的高频外设。过流保护、电压阈值检测、掉电预警,这些都是“只要一个电平跳变事件”的需求。比较器的输出可以直接触发中断,也可以接到定时器的刹车输入,实现硬件级别的紧急保护。我在一个电机驱动板上就是这么用的:采样电阻上的压降进比较器,一旦超过设定阈值,定时器PWM立即刹车,比软件检测快一个数量级。
更特别的是USB PD PHY。这颗芯片内置USB2.0全速控制器,同时集成了PD物理层,可以做Type-C接口的DFP/DRP检测,也能跑PD协议协商。这意味着做Type-C受电设备时,不需要再外挂一颗协议芯片,一颗CH32L103既完成协议通信,又完成整机逻辑控制。这个特性在同价位MCU里是稀缺卖点,接了Type-C项目的朋友可以重点考虑。
1.3 算账式选型:便宜芯片不等于便宜方案
很多工程师选型时只看芯片单价,这其实是最大的误区。工业产品的成本要算整板BOM、PCB面积、生产测试、返修率。一颗MCU便宜两块钱,但外面多挂一颗运放、一颗触摸芯片、一颗PD协议IC,总价反而高了。
举个例子:一个带触摸按键的便携仪表,如果MCU不自带触摸检测,要么用专用触摸芯片,要么自己搭RC充放电电路再用ADC采样,两种方案都要额外元件和校准时间。CH32L103自带TouchKey模块,直接铺几个焊盘就能做出触摸按键,生产时不用额外贴片,软件里跑一下自校准就行。这种省下来的隐性成本,比MCU芯片本身的价差更有价值。
小封装也一样。TSSOP20可以塞进很多原来用8位单片机才放得下的空间,但性能和外设完全是32位级别。如果产品尺寸是硬约束,选一颗高集成度的芯片有时比刻意追求低价更有意义。
2. 低功耗实践:模式选择、漏电流排查与续航估算
2.1 睡眠/停止/待机三种模式怎么选:一张表看清差异
CH32L103和大多数低功耗MCU一样,提供了睡眠、停止、待机三档低功耗模式。三者的功耗、唤醒源和恢复方式差别很大,选错了轻则功耗不达标,重则唤醒后程序跑飞。
| 模式 | CPU | 外设时钟 | 典型电流量级 | 唤醒源 | 唤醒后行为 |
|---|---|---|---|---|---|
| 睡眠 | 停止 | 可配置继续运行 | mA级往下 | 任意中断 | 从原指令继续执行 |
| 停止 | 停止 | 大部分关闭 | uA级 | EXTI、RTC等 | 从中断处继续,但时钟需重新初始化 |
| 待机 | 停止 | 几乎全关 | 最低 | RTC、唤醒IO、复位 | 类似复位重启,程序从头运行 |
睡眠模式适合“任务间隙短睡”的场景,比如主循环里等待串口指令,等一条1ms的定时器中断唤醒做一次状态刷新。停止模式适合需要保持RAM数据、且唤醒后还想接着原来逻辑走的情况,很多电池设备的主休眠态都用这一档。待机模式适合唤醒后直接重新初始化的场景,比如RTC定时唤醒采集一轮数据,采完继续睡,完全不需要保留唤醒前的运行现场。
我自己的习惯是:优先用停止模式做常态休眠,因为既能保住运行现场,功耗又能压到uA级。只有当静态功耗实在压不下去、或者唤醒本身就是一次“重新开机”,才会用待机模式。
2.2 唤醒之后时钟“变了”:停止模式恢复代码框架
停止模式下大部分时钟停止,唤醒后系统时钟并不一定自动恢复到原来的96MHz配置。如果不重新初始化时钟,轻则串口波特率不对,重则外设时序全部错乱。这是低功耗开发里最容易踩的坑。
可以参考下面的框架代码来理解这个流程:
// 进入停止模式,WFI等待唤醒 // 以官方EVT中CH32L103例程为准 PWR_EnterSTOPMode(PWR_STOPEntry_WFI, PWR_STOPMode_LP); // 唤醒后的第一条工作:恢复系统时钟 SystemInit(); // 如果是内部时钟方案,重新配置HSI/PLL // 接着重新初始化用到的外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);为什么唤醒后要调用SystemInit?因为在停止模式下PLL和HSE/HSI可能都被关闭,唤醒后系统默认跑到低速时钟或者未锁定状态。直接操作外设会得到错误时序。我把这个步骤称为“唤醒三板斧”:恢复时钟、重配时钟树、重新初始化用到的外设。顺序不能反,先有时钟才能操作寄存器。
另外要注意,睡眠模式唤醒后不需要恢复时钟,因为睡眠模式只停了CPU核心,系统时钟和外设时钟仍然是开着的。这也是为什么短睡场景用睡眠模式更合适的原因之一。
2.3 电流从哪漏掉:GPIO浮空、外部电路和测量陷阱
芯片手册上的uA级待机电流是在理想条件下测出来的,但实际整板电流经常高出几十倍。我排查过很多次低功耗异常,最经典的漏电路径有三个。
第一个是GPIO浮空。CH32L103复位后未使用的引脚默认可能是浮空输入状态,CMOS输入级在输入电平不确定时会出现穿透电流,单个引脚多出来的电流不大,但几十个引脚加起来非常可观。解决方法是把所有未使用引脚配置成模拟输入或者推挽输出低电平,在进入低功耗之前统一处理。
for (uint8_t i = 0; i < TOTAL_PINS; i++) { GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 或推挽输出低 GPIO_Init(GPIOx, &GPIO_InitStructure); }第二个是外部电路。MCU睡了,但板上的电阻分压网络、传感器、LED限流电阻还在耗电。比如电池电压检测用的两个100k分压电阻,在低功耗模式下依然从电池抽电,电流大约5V/200k=25uA,直接毁掉整个低功耗设计。对策是给这些电路串联MOS管开关,或者用MCU GPIO控制传感器电源,只在采集瞬间开启。
第三个是测量陷阱。调试器挂在SWIO上时,目标板电流测不准,因为调试器本身在供电和维持通信。我习惯用精密电源或uA表直接给目标板供电,断开调试器再读数。用万用表电流档时也要注意量程内阻,建议先短路开机,等系统稳定后再断开短路线串电流表,否则启动瞬间的大电流会在电流档内阻上产生压降,导致MCU复位。
2.4 用状态机管理休眠流程:从采集到唤醒的代码结构
低功耗设备的代码最忌讳在中断服务函数里就地休眠。中断里跑休眠逻辑,不仅可读性差,还容易因为事件标志没有正确处理,导致醒来后不知道下一步干什么。我习惯用一个4状态的小状态机来管理:NORMAL、PREPARE_SLEEP、SLEEP、RESUME。
typedef enum { ST_NORMAL, ST_PREPARE_SLEEP, ST_SLEEP, ST_RESUME } SysState; SysState currentState = ST_NORMAL; volatile uint8_t event = 0; // 主循环 while(1) { switch(currentState) { case ST_NORMAL: // 执行一次采集任务 if (采集完成) { event = EVT_MEASURE_DONE; currentState = ST_PREPARE_SLEEP; } break; case ST_PREPARE_SLEEP: // 关闭传感器电源、未用GPIO配置为AIN DisablePeripherals(); currentState = ST_SLEEP; PWR_EnterSTOPMode(PWR_STOPEntry_WFI, PWR_STOPMode_LP); // 唤醒后回到这里 SystemInit(); currentState = ST_RESUME; break; case ST_RESUME: InitPeripherals(); currentState = ST_NORMAL; break; } }这样做的优势是每个状态里只做一件事,出问题可以加日志追踪。实际项目中,RTC中断只负责置一个”该醒了”的标志,真正的恢复动作都放在状态机里做。中断里处理的事情越少,系统的确定性越好。
2.5 电池能用多久:平均功耗与容量估算
续航估算不需要多高深的公式,关键是把“平均电流”算准。平均电流不是某一时刻的电流,而是各模式电流按时间占比加权:
平均电流 = (运行时间×运行电流 + 睡眠时间×睡眠电流) / 总时间 续航小时 = 电池容量(mAh) / 平均电流(mA)举个例子,一个传感器每隔10秒采集一次,单次采集耗时50ms、电流10mA,其余时间停止模式20uA。那么平均电流大约是:
平均电流 = (0.05×10 + 9.95×0.02) / 10 ≈ 0.0699 mA如果用一节600mAh的锂电池,理论续航大约 600/0.0699 ≈ 8584小时,约357天。但实际还要考虑电池自放电、DC-DC转换效率、温度下降导致的容量衰减,工程上通常按理论值的一半到三分之一来预估更稳妥。我用这个粗算方式做过很多个低功耗方案,给需求方报续航时留足余量,后期少很多麻烦。
3. 外设配置指南:GPIO、ADC、定时器与DMA的落地要点
3.1 先画引脚分配表,再做GPIO复用与重映射
CH32L103的封装不大,QFN28和TSSOP20都是“脚少事多”的类型,引脚规划是硬件工程师要仔细做的功课。我的习惯是在开写代码前,先在表格里把每个引脚的用途、功能模式、是否可重映射列出来,避免最后发现某个外设引脚跟另外一个功能打架。
| 引脚 | 默认功能 | 复用功能 | 备用功能 | 项目分配 |
|---|---|---|---|---|
| PA0 | GPIO | ADC通道 | OPA输入 | 温度采集 |
| PA1 | GPIO | UART2_TX | 比较器输入 | 串口调试 |
| PB4 | GPIO | SPI1_NSS | TIM3_CH1 | BLDC霍尔采样 |
GPIO初始化本身不复杂,关键是复用功能的配置要和实际需求匹配。下面是一段典型的复用推挽输出配置:
GPIO_InitTypeDef GPIO_InitStructure = {0}; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 若引脚需要重映射到其他位置,打开重映射功能 GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);需要提醒的是,不同封装的可用引脚数量不同,TSSOP20上很多复用功能物理上就不存在。一定先翻数据手册里的引脚定义表,确认这个封装下外设引脚是否真的引出。我见过一个同事从QFN28原理图直接复制到TSSOP20,结果USART1_TX映射的引脚在封装里根本没有,板子打回来才发现。
3.2 ADC采集链路:采样时间、信号源阻抗与内部OPA配合
CH32L103的ADC是12位逐次逼近型,支持规则组和注入组,采集精度完全够工业传感使用。但ADC用不好,往往不是分辨率问题,而是采样保持电路和信号源阻抗的匹配问题。
如果信号源阻抗过高,采样电容充电时间不够,ADC采样结果会偏低且跳动。解决办法有两个方向:一是增大ADC采样周期,给它更多充电时间;二是在信号源和ADC之间加一个运放做缓冲,利用运放的低输出阻抗驱动ADC采样电容。CH32L103内部运放正好可以用在这里,省掉外部跟随器。
ADC_InitTypeDef ADC_InitStructure = {0}; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239_5); ADC_Cmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t value = ADC_GetConversionValue(ADC1);实操中我会把采样率要求不高的通道采样时间尽可能调大,比如工业传感器输出阻抗一般都在10k以上,采样时间取最长档位,测出来的数据稳定性会好很多。用OPA做跟随之后,采样时间就可以适当缩小,换取更高吞吐率。
比较器在采集链路里的角色更偏“守护”。比如用比较器监测电源轨,一旦电压低于阈值就触发紧急中断,在掉电完成前把关键参数写入Flash。这个功能在很多工业设备里都是刚需,比软件轮询可靠得多。
3.3 高级定时器与PWM:电机控制场景的可玩性
CH32L103虽然定位低功耗,但它的高级定时器能力一点不像低功耗芯片。互补PWM、死区插入、刹车输入这些传统电机控制必备的功能都有。对于小功率BLDC或者PMSM的方波控制、几瓦到几十瓦量级的驱动板,用它可以做得很紧凑。
高级定时器的配置项比普通定时器多不少,核心的几个参数是:预分频器决定PWM频率基准,自动重载值决定周期,比较值决定占空比,死区时间寄存器决定上下桥臂换相时的间隔。还有刹车输入,可以配置成低电平有效或高电平有效,一旦触发,PWM输出立即进入安全状态。
我把比较器输出接到定时器刹车输入的做法在这颗芯片上再次验证是可行的:硬件过流,比较器翻转,定时器PWM立刻关闭,完全不需要软件参与。这个设计在电机驱动、开关电源这类对保护速度有要求的场景里非常实用。
普通定时器还可以做编码器接口模式,配合霍尔传感器或者增量编码器读位置和速度。工业传感设备里这种“低速+高可靠”的控制需求,这颗芯片完全覆盖得住。
3.4 DMA与UART/SPI:不占用CPU的数据搬运方案
低功耗MCU的省电原则里有一条:让CPU尽快回到睡眠,把数据搬运这种事情交给DMA。CH32L103有DMA控制器,常见的恒温采集、串口收发都可以交给它。
串口接收是我最常用的DMA场景。配置DMA循环模式接收数据,接收缓冲是环形缓冲区,DMA每收一个字节就往缓冲区写一次,当串口空闲中断来临时,CPU只要一次性把缓冲区的完整帧解析掉。这样做的好处是主循环大部分时间不用管串口,也不用逐字节读数据寄存器,CPU利用率大幅下降。
// DMA接收串口数据到缓冲区的框架示意 DMA_InitTypeDef DMA_InitStructure = {0}; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); DMA_Cmd(DMA1_Channel5, ENABLE);ADC连续采集也可以开DMA,让ADC转换结果自动存数组,主循环定期取平均值即可。这种“采集走DMA、CPU按时醒来处理一轮”的模式,是低功耗工业传感设备的典型写法。
4. 工业选型判断:适合做什么,别硬做什么
4.1 主场场景:工业变送器、便携仪表与触摸面板
CH32L103最适合的其实就是中小规模工业控制设备。两线制4-20mA变送器是典型场景,整机功耗需要控制在4mA以内,传感器、MCU、输出电路全部要精打细算。它的uA级睡眠电流和快速唤醒能力让这类设备可以“睡一会儿、采一会儿、回传一会儿”。
便携检测仪也是很好的匹配。手持设备用锂电池,对外设的需求通常就是ADC采传感器、串口或者蓝牙模块通信、按键操作。内置运放把传感器信号调理好,触摸按键替代机械按键解决防水防尘问题,QFN28封装让整机可以做得很小。工业现场面板类似,触摸按键、小屏、Modbus通信,这颗芯片做起来很顺手。
如果项目需要在掉电前保存参数,内置比较器可以直接监测电源跌落,触发中断后进入Flash写入流程。再加上独立看门狗防止程序跑飞,工业可靠性设计需要的几个要素都齐了。
4.2 Type-C PD设备:受电端与协议协商
内置PD PHY让它成为Type-C外设里的好用选项。像电动工具、蓝牙音箱、小家电这类用Type-C接口充电的产品,以前需要一个协议芯片负责PD诱骗,一个MCU负责整机逻辑,现在一颗芯片两个角色一起干。
作为受电端,CH32L103可以识别适配器的PD能力,并发出请求获取合适的电压档位;作为DRP或者Source端,它也可以做角色检测和协商。缺点是它本身不是电源管理IC,大功率的开关电源控制还是要靠专门方案。但协议协商、状态显示、充电曲线管理这些逻辑层工作,它做起来绰绰有余。一颗带PD功能的Type-C设备,整机从硬件到软件都可以围绕CH32L103来组织。
4.3 别硬上的场景:Linux、大存储和工业以太网
选型不只看“它能做什么”,更要看“它不该做什么”。CH32L103只有几十KB Flash和20KB级别的RAM,跑Linux想都不要想。如果产品需要一个完整的GUI框架、需要动态加载模块,那该上MPU还是上MPU。
本地大量日志存储也不适合。如果每分钟都记录一条带时间戳的日志,Flash很快会被写满,而且频繁擦写会缩短Flash寿命。这种需求最好外挂Flash芯片或者选大容量型号。
需要工业以太网的项目也建议慎重。CH32L103没有内置以太网MAC,外接Ethernet PHY没有意义,需要走SPI接口的W5500这类网络芯片来实现。如果你对网络吞吐有比较高要求,选一颗带MAC的MCU更合适。
还有一点,如果产品需要蓝牙低功耗,这颗芯片本身不带BLE。虽然可以通过串口外挂BLE模块,但如果你追求“一体解决”,建议去看带蓝牙的MCU型号。选型时把通信方式先定下来,再决定用不用CH32L103,比拿到芯片后才发现少功能要省事得多。
4.4 横向评估清单:拿什么指标和同类MCU比
做MCU选型对比时,我一般列一个清单,逐项打分,不只看单一维度:
| 评估维度 | 重点观察项 |
|---|---|
| 功耗指标 | 停止/待机电流、唤醒时间、RTC功耗 |
| 模拟资源 | ADC位数和采样率、运放数量、比较器响应 |
| 协议集成 | USB/PD/CAN/以太网是否有硬件支持 |
| 封装选择 | 引脚数、封装尺寸、设计匹配度 |
| 工具链 | IDE是否免费、例程是否完整、调试器是否易用 |
| 供货与文档 | 手册质量、勘误表、原厂支持力度 |
和同价位Cortex-M系列比,CH32L103的特点是“小封装里的高集成度”。如果你需要的正好是低功耗+模拟采集+Type-C PD,它的竞争力很强。如果需求是跑复杂协议栈、大内存应用,那它会很难受。选型不是找“最强芯片”,而是找“刚好匹配”的芯片。
5. 开发环境、硬件设计与调试避坑实录
5.1 开发环境快速上手:MounRiver Studio与EVT例程
开发CH32L103最省力的方式是直接用MounRiver Studio,它是沁恒基于Eclipse做的IDE,内置了RISC-V GCC编译器、调试插件和下载工具,装完就能编译烧录。新建工程时直接选CH32L103芯片型号,会自动生成启动文件和链接脚本,不需要自己折腾。
官方会提供一个叫CH32L103EVT的示例工程压缩包,解压后每个外设都有独立Demo目录:GPIO、ADC、OPA、COMP、TIM、SPI、I2C、USART、USB、PD、TouchKey这些全都有。我最推荐的起步顺序是:先跑GPIO翻转,确认开发环境通;然后再跑ADC和OPA例程,熟悉模拟外设配置;最后再碰低功耗和PD相关例程,因为这两个涉及的状态机关系相对复杂。
EVT里的代码质量比较高,但毕竟是通用示例,上项目前建议把底层外设初始化重新梳理一遍,删掉用不到的部分,降低Flash占用。
5.2 烧录调试中的隐蔽坑:待机模式连不上怎么办
调试低功耗代码时最典型的尴尬场景是:程序执行到PWR_EnterSTANDBYMode之后,调试器就再也连不上了。这是因为待机模式下调试访问基本关闭,此时点击下载,OpenOCD会报连接失败。
解决方法其实很简单:按住板子上的复位键,让芯片保持在复位状态,然后在IDE里点下载,点击后瞬间松开复位键,烧录器会在芯片重新上电运行前抓住设备。或者用官方调试器配合“下载前自动复位”的选项,也能绕开这个问题。
如果芯片进入的是停止模式而不是待机模式,一般还能通过调试器唤醒。但保险起见,调试低功耗代码时我通常先屏蔽掉真正进入低功耗的语句,用一个延时替代,确认其他功能正常后再打开。这样能避免“程序跑哪去了都不知道”的情况。
另一个坑是SWIO调试引脚被复用。如果量产的固件里把SWIO引脚配成了其他功能,后续升级固件时下载器连不上会非常麻烦。我建议在产品上预留一个隔离点,SWIO通过0欧电阻或者焊盘跳线接到调试器接口,量产固件正常工作时该引脚尽量保持可调试状态。
5.3 硬件设计细节:电源滤波、复位、触摸走线与调试口规划
硬件侧的功夫同样不能省。电源上,每个VDD引脚旁边放一个0.1uF陶瓷电容,位置尽量贴近引脚;整体再加一个10uF钽电容或陶瓷电容做低频去耦。VDDA模拟电源建议串一个磁珠或者小电阻再接入,避免数字电路噪声通过电源耦合进ADC。这个细节对12位ADC的采样精度影响很大。
复位电路不需要太复杂,10k上拉电阻加0.1uF对地电容就够用。如果需要更高的可靠性,可以加外部复位芯片,但大部分工业场景下简易RC复位搭配内置上电复位就够了。
触摸按键的走线有讲究。TouchKey检测依赖电极对地的寄生电容,走线越长、途经区域越靠近高频信号,误触发的概率越高。我习惯把触摸电极焊盘放在板边,走线尽量粗短,周围用地铜皮包裹,不要和PWM信号线平行。如果是金属外壳设备,更要预留绝缘层或者远离金属结构件。
时钟方面,CH32L103支持内部时钟启动,很多应用可以省掉外部晶振。但如果你要跑USB全速或者对串口波特率精度有较高要求,建议仔细评估内部时钟的精度是否满足,必要时还是放一颗外部晶振稳妥。设计上预留晶振焊盘,前期用内部时钟调试,后期如果精度不够再贴晶振,兼顾了成本、灵活性和风险。
最后分享一点个人心得
CH32L103这颗芯片,我用下来的整体印象是“麻雀虽小,五脏俱全”,但它并不是万能钥匙。选型时最好先画出整机功耗预算表,算清楚每个模块的电量分配,再决定主控休眠策略;同时对照外设清单,确认运放、比较器、PD、触摸这些集成功能是否真的能把外围电路省下来。如果这两个问题的答案都是“是”,把它放进设计里基本不会错。拿到评估板之后,先别急着跑Demo,把一颗LED接在未使用引脚上,写一个“睡眠后LED是否意外点亮”的小测试,一个小时就能暴露整板的漏电路径。低功耗MCU的选型,芯片本身只是起点,整板功耗才是最终结果。