不只是PD诱骗:CH32X035这颗RISC-V通用MCU的隐藏技能
2026/9/24 13:20:46 网站建设 项目流程

最近群里聊CH32X035,十条有八条都在说PD诱骗,好像这颗RISC-V芯片就是为了“把充电器骗出20V”而生的一样。说实话,这个功能确实好用,我也拿它做过不少测试,但如果只盯着诱骗,那这芯片至少被你浪费了三分之二的功力。CH32X035是一颗完整的通用MCU,带USB Host/Device、内置OPA运放、模拟比较器、可编程IO控制器PIOC,还有一组可以输出互补PWM的高级定时器。这些东西组合在一起,能干的事情比“诱骗”多得多的多。

这颗芯片真正适合的人群,是那些想以极低成本做USB PD相关产品原型、想把手头Cortex-M的开发习惯平滑迁移到RISC-V、或者需要一个“MCU+模拟前端+电源协议”三合一方案的开发者。本文我会从开发环境、工具链、外设细节到完整实操案例,把这颗芯片的隐藏技能挨个拆开讲清楚,也顺便聊聊我从ARM转到RISC-V之后的一些真实感受。

1. 先聊清楚:CH32X035到底是一颗什么芯片

1.1 一颗披着“诱骗芯片”外衣的通用MCU

CH32X035并不是一颗专用电源芯片,它本质上是一颗基于沁恒青稞V4C内核的32位RISC-V微控制器,主频最高可以跑到80MHz,指令集是RV32EC。这个“E”代表嵌入式,去掉了乘除法指令,但这在单片机场景里影响不大,因为编译器会用软件库去模拟乘除法,在80MHz的频率下,绝大多数控制类任务根本感觉不到差异。

芯片内部集成的资源相当有诚意:12位ADC、多路高级定时器、USB2.0全速控制器、OPA运算放大器、模拟比较器、多路UART/SPI/I2C,再加上一个比较有特色的PIOC可编程IO控制器。这可不是一颗“点个灯、跑个串口”级别的入门芯片,它的定位更接近“带模拟前端和USB协议能力的工业控制MCU”。

很多人第一次接触CH32X035是因为PD诱骗例程,网上流传的demo代码也确实简单到让人怀疑人生——烧录之后,充电器就乖乖输出你设定的电压。但如果你打开数据手册看系统框图,会发现PD模块只是整个芯片的一个部分,它旁边还站着USB控制器、模拟外设和一堆定时器。恰恰是这些“旁边的模块”,才是这颗芯片拉开与其他国产MCU差距的地方。

1.2 为什么值得从“诱骗”跳出来看它

我接触过的很多开发者有个思维惯性,就是“芯片因为某个网红功能出名,那它就只能干这个”。早些年STM32因为USB功能出名,有人就觉得它是USB专用芯片,结果后来大家发现它几乎能干所有事情。CH32X035也是一样,PD诱骗只是它的技能之一,而且从芯片设计逻辑来看,PD模块更像是一个“附带赠品”,真正的主角是那颗内置USB控制器和模拟外设。

举一个很实际的应用场景:你要做一个智能电源工具,比如一台小型直流电子负载、一个电池内阻测试仪,或者一台便携电烙铁。传统方案你需要一颗MCU做控制和显示,一颗PD诱骗芯片去和充电器握手,再外置一颗运放做电流采样放大,可能还要一颗比较器做保护。现在用CH32X035,一颗芯片全包了。PD诱骗负责从充电器获取高电压,OPA负责把采样电阻上的微弱电压放大到ADC能量程,比较器负责过流快速关断,高级定时器负责输出PWM控制功率管,USB还能顺带做参数配置和固件升级。

一颗芯片干一整个板子的活,这才是CH32X035真正的价值。所以我在后面的内容里,会围绕这些“隐藏技能”展开,每个功能都会讲原理、讲配置、讲实操,最后用一个具体案例把它们串起来。

2. 开发环境与上手体验

2.1 从ARM切到RISC-V,工具链的适应期

先说实话,最早听说RISC-V的时候,我和大多数人的想法一样:生态肯定很拉胯,开发工具肯定难用,资料肯定少得可怜。但真正上手CH32X035之后,这个印象被刷新了。沁恒官方提供的MounRiver Studio(MRS)是一个基于Eclipse的IDE,界面风格和STM32CubeIDE、Keil这些老熟人非常接近,下载安装之后,新建工程直接就能选芯片型号,不需要自己去配GCC工具链,也不需要折腾OpenOCD脚本,开箱即用的程度非常高。

当然,从ARM切过来还是有几个地方要适应的。最明显的是调试器,Cortex-M系列用ST-Link/J-Link,到了RISC-V这边,常用的是WCH-LinkE或WCH-Link,它们支持RISC-V调试协议,也能兼容ARM调试。接线方式几乎是通用的,SWDIO、SWCLK、GND、3V3,四个引脚搞定,如果你之前用过DAP-Link,那上手成本基本为零。

有一点需要特别提醒:如果你之前用的是ST-Link,插到CH32X035上是没有反应的,不要怀疑芯片有问题,是协议不匹配。我一开始就踩过这个坑,把ST-Link插上去,IDE里始终识别不到芯片,翻了好久资料才发现是调试器选错了。微信群里还有人拿J-Link去连RISC-V芯片,折腾一晚上最后发现J-Link不支持,白白浪费时间。

2.2 WCH-LinkE接线与最小系统

WCH-LinkE有两种工作模式,固定在ARM模式还是RISC-V模式,取决于固件和跳线设置。连接CH32X035的时候,务必确认调试器处于RISC-V模式。我通常的做法是:上电之前把WCH-LinkE的mode引脚和GND短接,然后插入USB,此时指示灯的状态会提示当前模式,具体闪烁方式在说明书里有,不同批次可能略有差异,以官方文档为准。

最小系统这块,CH32X035和绝大多数MCU一样,3.3V供电,VDD和VSS之间放几个100nF去耦电容,再加一个大电解电容防止电压跌落。复位引脚可以悬空,但建议串一个10k电阻上拉到3.3V,这样能避免复位脚受干扰导致芯片意外重启。BOOT引脚默认拉低就行,不需要额外配置。

如果你要使用PD诱骗功能,电源部分要多看一眼。PD通信需要芯片、电压转换逻辑和CC线之间建立正确连接,通常PA9和PA10这两个引脚是CC1、CC2的复用脚,它们必须通过配置寄存器启用内部下拉或上拉电阻。很多人第一次调PD诱骗失败,问题往往就出在这里——芯片没把CC引脚上的电阻配置对,导致和充电器的握手过程根本没建立起来。

2.3 用库函数写第一段代码

CH32X035的固件库风格非常接近STM32的标准外设库,GPIO初始化的写法是GPIO_InitTypeDefRCC_APB2PeriphClockCmdGPIO_Init这一套,如果你之前写过STM32F1系列,看这些代码会觉得格外亲切。对于从标准库迁移过来的老手,基本不需要查资料就能直接上手改代码。

新建工程的第一步是选芯片型号,MRS新建工程向导里直接搜CH32X035,选对应封装即可。工程会自动生成main.cch32x035_it.c(中断处理)和一堆系统文件。编译和烧录也非常流畅,编译完直接点下载按钮,WCH-LinkE就会自动完成擦除、写入、校验,整个过程比Keil配合ST-Link还要顺滑。

第一次跑代码,我建议先点个灯。用库函数初始化GPIO、拉高引脚、加个Delay_Ms(这个延时函数在库文件里自带),整个过程五分钟以内就能完成。跑通了点灯,就等于验证了工具链、调试器、最小系统、烧录流程这一整条链路都是通的,后面再去调PD、USB这些外设,心里就有底了。

3. 隐藏技能逐一拆解

3.1 USB PD诱骗:不止“要电压”这么简单

PD诱骗是CH32X035的当红功能,但很多人只知道“调用一个函数就能得到电压”,不知道背后发生了什么。USB PD协议本质上是一种基于CC线的通信协议,充电器和设备之间通过配置通道(Configuration Channel)交换“能力数据包”,设备向充电器请求自己想要的电压和电流档位,充电器回复确认后,VBUS就会切换到目标电压。

CH32X035内置了PD的物理层收发器和协议逻辑,不需要外接FUSB302这类PD协议芯片。在软件层面,你只需要初始化CC引脚的上下拉电阻,然后调用库函数直接请求目标电压。比如想要9V,就配置请求PDO为9V档位;想要20V,就配置为20V档位。一切都封装好了,开发者几乎不需要关心PD协议的细节。

不过这里有个认知盲区要讲清楚:PD诱骗不是“骗”,而是USB PD协议的正常应用。设备按照标准流程发起请求,充电器按照标准流程响应,这和“绕过协议、白嫖电压”完全是两回事。所以用它做正儿八经的产品原型,在合规性上没有任何问题。

实际操作中我建议你做一个按键切换电压的测试板,通过按键在5V、9V、12V、15V、20V之间循环切换。这样能直观感受PD协议的过程:每一次切换,充电器的VBUS输出都会有几十毫秒的拉低再上升动作,这是协议重新协商的正常现象。如果切换电压后输出迟迟不稳,就要检查CC引脚的配置了。

3.2 USB Host/Device双角色

CH32X035集成了USB2.0全速控制器,更关键的是它同时支持Host和Device两种角色。也就是说,这颗芯片既可以当USB外设连接到电脑,也可以作为主机去读取U盘、键盘、鼠标等设备。这一点在同类国产MCU里相当少见,很多Cortex-M0级别的芯片只有Device功能。

做Device模式很简单,官方提供了USB转串口的例程,烧录后把PA11、PA12接到电脑USB口,电脑上就会枚举出一个虚拟串口,往串口发数据就能在电脑上收到,反向亦然。这个功能配合PD诱骗很有意思:设备从充电器取电的同时,还能通过USB口和电脑通信,一个接口同时解决供电和数据传输,这在便携设备开发中非常实用。

Host模式更有玩头。你把U盘插到芯片的USB口上,芯片可以做文件系统级的读写。我知道有开发者拿它做离线固件升级器,把固件放在U盘里,插上设备就能自动烧录到目标芯片,这套方案在产线上非常实用。也有做数据采集器的,把传感器数据写入U盘,形成批量日志文件,现场巡检的时候直接拔U盘走人。这些场景如果放在以前,你必须用树莓派或者带USB Host的Linux开发板,成本和功耗都下不来。

3.3 内置OPA运放与模拟比较器

模拟外设是CH32X035区别于同类MCU的一个显著卖点。芯片内部集成了OPA运算放大器,这个运放是可以用软件配置放大倍数的,还可以配置成跟随器、同相放大、反相放大等常见拓扑。对于没有模拟电路设计经验的开发者来说,这个功能可以帮你省掉一片外置运放芯片,同时省掉一大片布局布线的麻烦。

举个例子,你要做一个电流检测功能,最简单的方案是采样电阻加上运放,把毫伏级别的压差放大到ADC能分辨的范围。传统方案需要在外围选运放型号、配反馈电阻、算放大倍数,现在直接在代码里配置OPA的增益,然后从ADC通道读取结果,硬件成本几乎为零。CH32X035内置的模拟比较器也很有用,它可以把采样电压和一个由DAC或参考电压设定的阈值做比较,输出直接触发定时器刹车或者外部中断。这意味着过流保护可以在硬件层面完成,不需要CPU软件干预,响应速度是微秒级的。

说句公道话,这个OPA的性能和专用运放芯片还是有差距,精度和温漂都不能按仪表级的指标来要求。所以我的建议是:做消费类、工业控制类产品完全够用,但如果你做的是高精度仪器仪表,或者需要放大微伏级别的信号,还是老实外接精密运放吧。

3.4 PIOC可编程IO控制器

PIOC是CH32X035一个很有特色但容易被忽略的外设。简单来说,它是一个可编程的IO控制单元,可以在不占用CPU的情况下,按照预设的时序表去控制IO引脚的电平翻转。它内部有一张可配置的IO控制表,每个表项可以定义某个引脚在某时刻输出高电平或低电平,然后硬件自动按顺序执行,从而实现各种串行时序协议。

这个功能的实用价值非常大。比如你要和一颗单总线温度传感器通信,传统写法是用定时器中断去模拟时序,稍微有点其他中断干扰就会导致时序错乱。用PIOC的话,你把单总线的读写时序预先写好,配置好时间参数,然后启动它的控制流程,CPU就可以去干别的事了,时序由硬件精确保证。

PIOC还可以用来模拟DVP数字摄像头接口、红外遥控解码、LCD的并口通信等。它本质上是一个“用硬件描述时序”的引擎,灵活度比固定功能的硬件外设更高,但又比纯软件模拟更可靠。我在实际项目里用它模拟过红外接收,效果出乎意料地稳定——之前用软件解码,时不时会因为定时器中断抢占导致解码失败,换成PIOC之后这个毛病彻底消失了。

4. 实操案例:做一个PD诱骗电压监测小工具

4.1 整体架构与元器件选择

前面的内容偏原理,这一节我拿一个实际项目来收拢一下。这个项目的目标是做一个PD诱骗电压监测器:插在充电器上,通过按键切换诱骗5V/9V/12V/15V/20V,OLED屏幕显示当前请求电压、实际输出电压和电流,同时通过USB虚拟串口把这些数据实时发送到电脑端。

整个项目用到的CH32X035内部资源包括:PD模块(诱骗电压)、ADC(采样输出电压和电流)、GPIO(按键和OLED控制)、I2C或SPI(驱动OLED)、USB Device(虚拟串口)。这基本上把芯片的主要外设都串起来了。元器件方面,除了核心板和两块0402的采样电阻,还需要一个OLED屏幕和两个轻触按键,成本加起来不到十块钱。

采样电阻的选型有一个经验值:电流采样电阻阻值不要太大,否则压降和功耗都很可观。我选用的是20毫欧的合金电阻,最大电流3A时压降60mV,功耗0.18W,配合OPA放大20倍之后,ADC输入范围就是1.2V,在12位ADC下分辨率大约是0.6mV,对应的电流分辨率是0.03A,精度完全够用。

4.2 关键代码配置

代码的骨架可以分为几个模块:PD初始化与请求、ADC与OPA采样、OLED显示、按键扫描、USB虚拟串口。这里我挑几个最有代表性的配置细说。

PD初始化比较重要的是CC引脚的配置和请求电压的设定。官方库提供了一个PD初始化函数,它会自动配置CC引脚的上下拉和PD物理层参数。之后调用电压请求函数时,传入目标电压值即可。需要注意的是,请求电压必须匹配充电器支持的PDO档位,如果你请求一个充电器不支持的电压,协议协商会失败,VBUS会停留在5V。

void PD_Task(uint16_t target_mv) { /* 检查当前是否有充电器连接 */ if (PD_Device_IsAttached()) { /* 请求目标电压,单位mV */ PD_Request_Voltage(target_mv); } }

OPA和ADC的配置也很简单,先初始化OPA增益为20倍,然后初始化ADC通道为采样输入。采样的时候为了减少噪声,建议在代码里做多次采样取平均,或者开启ADC的硬件过采样功能。我这边的做法是每个通道连续采样8次,去掉最大值和最小值,剩下6次取平均,实测波动非常小。

uint16_t ADC_GetAverage(ADC_TypeDef* ADCx, uint8_t channel, uint8_t times) { uint32_t sum = 0; for (uint8_t i = 0; i < times; i++) { sum += ADC_ReadChannel(ADCx, channel); } return (uint16_t)(sum / times); }

USB虚拟串口这部分直接参考官方的USB CDC例程,把接收和发送的回调函数接好就行。实际测试下来,电脑端用串口助手连接,115200波特率下双向通信稳定,没有丢数据的情况。

4.3 实测效果与调试记录

整机焊接好之后,我把PD监测器插到一个支持65W PD的充电器上。上电默认请求5V,OLED显示当前电压4.98V,和万用表实测值几乎一致。按下按键切换到9V,OLED上的电压值在几百毫秒内跳变到8.94V,同时电脑端的串口软件收到了完整的切换日志,包括请求电压、实际电压、电流、功率等信息。

整个调试过程中最值得记录的一个问题是OPA的零点偏移。第一次上电时,没有接负载、电流为0的情况下,ADC读到的采样值却对应了约30mA的电流。排查下来发现这是OPA的输入失调电压在作祟,放大20倍之后,这个偏移被放大到了不可忽略的程度。解决的办法是在软件里做零点校准:开机时先记录一次无负载状态下的ADC原始值,把它作为基准,之后所有采样值都减去这个基准值,问题就解决了。

这个案例做完之后,我对CH32X035的判断发生了根本变化。它不只是一个“PD诱骗工具芯片”,而是一颗可以支撑完整产品原型的通用MCU。更难得的是,这个原型只用了一颗芯片和少量外围元件,如果换作传统方案,至少要多出一颗PD协议芯片和一颗运放芯片,PCB面积和物料成本都会明显上升。

5. 常见问题排查与避坑清单

5.1 现象、原因与方案对照表

说实话,做技术分享最没水分的就是“踩坑记录”,有些问题我自己折腾了很久才解决,这几条给到你,能帮你撕开不少时间。

现象常见原因解决方案
WCH-LinkE识别不到芯片调试器不是RISC-V模式,或接线错误确认mode引脚短接到GND,检查SWDIO/SWCLK是否接反
PD诱骗偶尔失败,电压卡在5VCC引脚上下拉配置错误或未初始化检查PD初始化代码,确认正确启用了CC1/CC2内部电阻
诱骗电压切换后输出跳动负载过大超过充电器PDO的电流能力降低负载电流,或请求更高电流档位(前提是充电器支持)
OPA输出零点偏差大运放输入失调电压被增益放大代码中做零点校准,开机时记录无负载基准值
USB Host枚举失败USB供电电流不足,部分设备启动电流大加外部供电,或选择低功耗外设
烧录后程序不运行BOOT引脚电平不对,或者复位电路有问题确认BOOT引脚拉低,复位脚加上拉电阻

这些坑里面,最不值得踩的是第一个和第三个。接线问题在动手之前花两分钟核对就不会出问题;负载问题则需要注意充电器标称功率和PDO电流档位的区别——一个65W的充电器,5V档位通常只有3A,20V档位才有3.25A,小马拉大车肯定要出问题。

5.2 几个值得长期保留的细节

除了上面这些具体问题的解法,还有几个我从项目一开始就不太重视、后来吃了亏才记住的设计习惯。

第一,RISC-V内核的中断向量表默认从Flash起始地址开始,如果你的程序需要用Bootloader跳转到App,App工程里必须正确配置链接脚本中的FLASH偏移量,否则中断一触发就会跑飞。这个和STM32的配置逻辑一样,但RISC-V工具链里如果你不主动修改链接脚本,默认值会覆盖整个Flash区域,跳转之后所有中断都会失效。有些读者问“为什么App里点灯正常、串口却一进中断就卡死”,多半就是这个原因。

第二,CH32X035的ADC通道和OPA输出之间存在内部连接关系,使用前务必查清数据手册的引脚复用表。我最初想当然地以为OPA的输出可以接到任意ADC通道,结果读出来的数据一直是零,翻手册才发现OPA输出默认只连接到固定的几个内部通道,外部引脚对应的ADC通道并不会采集到OPA的信号。复用关系这事儿,任何MCU都别想当然,以手册为准。

第三,也是我个人的一个习惯:所有涉及PD诱骗的测试,都在回路里串一个电流表或者功率计。因为一旦配置错误,输出电压可能比你预想的高很多,直接烧坏后级电路。测试PD和高功率输出时,养成“先串仪器再上电”的习惯,可以帮你保住一批宝贵的原型板。

最后再分享一个体会吧。从Cortex-M切到RISC-V,我的感受是“差异比想象中小,惊喜比想象中多”。差异小是因为沁恒把工具链和库函数都做得很贴近传统单片机开发习惯;惊喜多是因为RISC-V开源指令集的自由度,让芯片厂商能更方便地把PD控制器、USB控制器、PIOC这些个性化的外围电路塞进同一颗芯片,而不是像Cortex-M那样大家都做得大差不差。CH32X035这颗芯片的定位很有趣,它补全了入门级RISC-V MCU在模拟外设和USB Host能力上的短板,也让“一颗芯片搞定一个电源产品”从想法变成了现实。如果你手头正好有USB PD相关的项目,或者在纠结要不要试试RISC-V,买一块CH32X035的开发板,按照这篇文的思路把隐藏技能挨个试一遍,相信你会有自己的判断。

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

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

立即咨询