资讯动态

不只是PD诱骗:CH32X035这颗RISC-V通用MCU的隐藏技能

发布时间:2026/9/24 13:20:48 来源:尧图企业网站定制
最近群里聊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 一颗披着“诱骗芯片”外衣的通用MCUCH32X035并不是一颗专用电源芯片它本质上是一颗基于沁恒青稞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 StudioMRS是一个基于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_InitTypeDef、RCC_APB2PeriphClockCmd、GPIO_Init这一套如果你之前写过STM32F1系列看这些代码会觉得格外亲切。对于从标准库迁移过来的老手基本不需要查资料就能直接上手改代码。新建工程的第一步是选芯片型号MRS新建工程向导里直接搜CH32X035选对应封装即可。工程会自动生成main.c、ch32x035_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/20VOLED屏幕显示当前请求电压、实际输出电压和电流同时通过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的充电器上。上电默认请求5VOLED显示当前电压4.98V和万用表实测值几乎一致。按下按键切换到9VOLED上的电压值在几百毫秒内跳变到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档位通常只有3A20V档位才有3.25A小马拉大车肯定要出问题。5.2 几个值得长期保留的细节除了上面这些具体问题的解法还有几个我从项目一开始就不太重视、后来吃了亏才记住的设计习惯。第一RISC-V内核的中断向量表默认从Flash起始地址开始如果你的程序需要用Bootloader跳转到AppApp工程里必须正确配置链接脚本中的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的开发板按照这篇文的思路把隐藏技能挨个试一遍相信你会有自己的判断。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价