只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Value⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 主芯片方案调试开发 -> 沁恒CH32_开发指南

沁恒CH32_开发指南

同系列 · 原理方案设计
扫码打开本页
微信扫码

沁恒 CH32 开发指南

编制日期 2026-10-14

从 MounRiver Studio 装不起来、WCH-Link 连不上,一路到量产烧录与 USB / PD 开发 —— 一份把「第一次上手会踩的坑」全部前置的工程手册

2+X
工具链只需装一个
MRS 自带 GCC / OpenOCD / 下载器
44
CH32V103 外设中断通道
另加 5 个内核中断,共 255 向量槽
2 线
调试口只需 2 个 IO
CH32V003 / M007 甚至只要 1 根
3.75 KB
出厂固化的 BootLoader
支持 USART1 与 USB 两种 ISP
128 B
用户选择字
含读保护位,误操作会整片擦除
80 MHz
CH32V103 最高主频
V30x 系列可达 144 MHz

结论:CH32 的开发链路比同价位 MCU 简单得多 —— 一个 MRS 装完就有「编译器 + 下载器 + 调试器 + OpenOCD」全套,片上 两线 SDI 调试口只需要两个 GPIO,出厂 BootLoader 又留了 USART1 与 USB 两条 ISP 后路。真正让人卡住的从来不是代码,而是三件小事: WCH-Link 停在 ARM 模式没切到 RISC-V、读保护一旦使能就把整片擦掉、USB 时钟没配到 48 MHz 就永远枚举不上。 本文按「装环境 → 建工程 → 编译 → 下载 → 调试 → 量产」的流水线的真实顺序组织,每一段都给出可复制的命令、可对照的表格、以及该段最常踩的坑。

报告总结

沁恒官网把 CH32 的资料拆得非常细:数据手册(DS)讲电气与引脚、参考手册 / 应用手册(RM)讲寄存器、 青稞微处理器手册讲内核、EVT 压缩包含评估板说明与几十个例程,而 MounRiver Studio 的用法又在另一个站点(mounriver.com)。 网上的中文教程绝大多数停留在「用 MRS 新建工程 → 点编译 → 点下载」这一步,一旦遇到连接失败、读保护、USB 枚举不上就无解。本文档做了三件官方分散文档没有做的事:

  • 把接力棒画清楚:明确指出「装 IDE」到「能断点调试」之间实际要经过哪几步,以及每一步做完了用什么现象验收。
  • 把坑写在坑发生的地方:不单独罗列「常见问题」,而是在讲每个环节时就把该环节的失效现象、原因、处置一起给出。
  • 标注来源与版本:所有数值型信息(引脚、电压、容量、寄存器地址、等待周期配置)都追溯到官方 DS/RM 的版本号。

读者路径

本文档共 19 章 + 4 个附录,按「先跑通、再理解」的顺序组织:

  • 只想尽快跑通第一个程序:第 4 章(装 MRS)→ 第 5 章(建工程点灯)→ 第 7 章(下载)→ 第 19 章(核查清单),四章足够。
  • 要做产品开发:第 2 章选型 → 第 3 章内核差异 → 第 6 章工程结构 → 第 16 章硬件设计。
  • 调不通、报错:直接翻第 18 章故障排查速查表,按现象分层定位。
  • 要写驱动:第 9 章 GPIO/EXTI → 第 10 章 PFIC → 第 11 章时钟 → 第 12 章外设 → 第 13 章定时器。
  • 从 STM32 切过来:第 17 章是专门的移植对照,先看这一章能省两三天。
  • 做 USB 或快充产品:第 14 章(含 USBHS 与 Type-C PD 资源矩阵)。
  • 做电池产品:第 15 章低功耗,注意「待机模式唤醒等于复位」这件事。

1 · 文档导读与阅读路径

这一章说明本文档的边界:覆盖什么、不覆盖什么,以及为什么把内容按「流水线」而不是按「功能模块」组织。

1.1 覆盖范围

本文档覆盖从拿到一块 CH32 最小系统板,到固件跑起来、能在断点处停下来、并能量产烧录的完整链路:

  • 家族与选型:CH32V / CH32F / CH32X / CH32L / CH32M 五大分支的规格对照,以及按「成本 / 主频 / 外设 / 封装」的选型号思路。
  • 内核:青稞 V2A / V3A / V4A / V4B / V4C / V4F 的差别,PFIC 中断控制器、HPE 硬件压栈、VTF 免表中断的原理与配置。
  • 开发环境:MounRiver Studio 的安装、工具链构成、首次配置、常见安装故障。
  • 工程与构建:官方 EVT 工程结构、启动文件、链接脚本、编译选项、体积优化。
  • 下载与量产:WCH-Link 三种硬件形态、两种工作模式、SDI 两线/单线接线、串口与 USB ISP、读保护与用户选择字。
  • 外设:GPIO / EXTI / PFIC / RCC / USART / SPI / I2C / ADC / DMA / TouchKey / 定时器 / RTC / 看门狗 / USB / PD。
  • 硬件与迁移:最小系统电路设计要点、从 STM32 移植的改动清单、批量排障。

1.2 不覆盖什么

以下内容超出本文档范围,需要时请查阅对应官方资料:

  • 蓝牙协议栈细节:CH32V208 的 BLE 5.3 协议栈 API、GATT 配置、射频认证(SRRC/CE/FCC)属于独立的无线文档。
  • 以太网协议栈深度用法:CH32V307 / V208 的 ETH + LWIP 移植细节属于例程包中的独立示例。
  • 每一款封装的完整管脚定义:本文档只给最常用封装的关键引脚(调试、自举、电源、USB),完整管脚表请查对应 DS。
  • 寄存器位域全集:RM 有近 300 页寄存器描述,本文档只给关键模块的常用位域,写代码时仍需对着 RM 核一遍。
  • 电机算法本身:CH32M007 的 FOC / 无感观测器算法属于电机控制理论,本文档只覆盖它的外设资源与调试接口。

1.3 版本与命名约定

CH32 的命名非常规整,看懂名字基本就能知道它属于哪一档。型号由「前缀 + 系列号 + 细分号」构成:

字段取值含义
前缀CH32V / CH32F / CH32X / CH32L / CH32MV = 青稞 RISC-V 内核;F = Arm Cortex-M3 内核;X = 带 USB PD 的连接型;L = 低功耗;M = 电机专用
系列号0 / 1 / 2 / 30 = 超值入门(V003);1 = 经典通用(V103/F103);2 = 增强 V2x 系列(V203/V208/F203);3 = 大容量 V3x 系列(V303/305/307/317)
细分号03/05/07/17/35同系列内按资源多少区分,数字越大通常资源越多
最容易混淆的一点

CH32V203 和 CH32F203 引脚与外设高度一致,但一个是青稞 V4B(RISC-V),一个是 Cortex-M3。 它们的参考手册是同一本 CH32FV2x_V3xRM,但内核部分完全不同 —— 下载工具要切 RISC-V 模式还是 ARM 模式,就是这一位字母决定的。

1.4 事实来源与免责

本文档所有数值型信息来自沁恒官方资料,章节正文中会标注出处。主要来源及版本如下:

资料版本提供的内容
CH32V103DS0.PDFV1.2(2024-03)V103 电气参数、引脚定义、封装、自举模式
CH32xRM.PDFV2.0(2025-10)CH32F103x / CH32V103x 应用手册,286 页,含全部外设寄存器
CH32V307DS0.PDFV3.9(2026-08)CH32V303/305/307/317 数据手册
CH32F203DS0.PDFV2.5CH32F203 数据手册
青稞处理器产品页与 QingKeV2/V3/V4 微处理器手册—HPE / VTF / XW / PFIC CSR 的定义
WCH-Link 产品页与 WCH-LinkUserManualV2.8调试器接线、模式切换、各芯片调试脚对照
以正式 datasheet 为准

沁恒的 RM / DS 修订非常频繁(仅 2026 年 CH32V307DS0 就更新到 V3.9),料号也会按 PCN 变更。文中引用某型号时一定标了版本; 正式立项前请到 wch.cn/downloads 复核目标料号的最新 DS 与 PCN 状态。特别提醒:青稞 V2A 是 RV32E 子集,只有 16 个通用寄存器, 编译选项配错会直接报链接错误,这一点在任何地方都不会被自动纠正。

CH32 开发的五段式流水线 —— 每一段做完都要有一个「能验收的标志」上一段没配对,下一段的症状一定伪装成别的东西① 硬件开发板 / 最小系统SDI 口 + BOOT0验收标志 ↓② 环境MounRiver Studio能建空工程并编译验收标志 ↓③ 构建GCC RV32 / LD 脚本产出 .elf / .hex验收标志 ↓④ 下载WCH-Link / ISP提示下载成功验收标志 ↓⑤ 调试断点 / SDI 打印能停在 main()验收标志 ↓本指南的写法:每一段都给「症状 → 原因 → 处置」三元组第 4~8 章走完流水线的中段;第 9~14 章是跑起来之后的外设细节;第 16~19 章是硬件、移植与排障。
图 1 · CH32 开发的五段式流水线与本文档的组织逻辑

2 · CH32 家族全景与选型

CH32 不是一个系列,而是沁恒 MCU 业务的整个货架。这一章先把货架摆在桌子上,讲清每个分支的存在理由,再给选型路径。

2.1 一句话认识 CH32

沁恒微电子(WCH,南京)长期做的是「连接」生意:USB 转串口芯片(CH340 系列)、USB HUB、蓝牙、以太网桥接芯片, 这些产品线给它攒下了USB PHY、以太网 PHY、蓝牙射频与协议栈三套自研 IP。CH32 就是在这三套 IP 之上, 配上自研的青稞 RISC-V 处理器内核(以及 Arm Cortex-M3 授权内核)搭出来的 MCU 货架。

这带来两个和其它国产 MCU 不太一样的特征:

  • USB 是真强项:CH32V103 就有「1 路 FS Host/Device + 1 路 FS Device」,CH32V307 更是做到 480 Mbps HS 且内置 PHY。做 USB 相关产品时,CH32 往往是成本最低的方案。
  • 调试口极省 IO:不用标准 4 线 JTAG,而是沁恒自己的两线 SDI(Serial Debug Interface),CH32V003 甚至只要 1 根线。这对 8 脚、16 脚的小封装意义重大。

2.2 两大阵营:青稞 RISC-V 与 Cortex-M3

选型第一刀永远是内核,因为它决定了整个工具链和调试器形态。CH32 里同时存在两条线:

对比项CH32V(青稞 RISC-V)CH32F(Arm Cortex-M3)
内核青稞 V2A / V2C / V3A / V4A / V4B / V4C / V4FCortex-M3(CH32F103 为 72 MHz,F203 为 144 MHz)
指令集RV32EC(V2A)/ RV32IMAC(V3A、V4x)/ RV32IMACF(V4F,带单精度浮点)Thumb-2
调试接口两线 SDI(SWCLK / SWDIO),V003 与 M007 支持单线标准 SWD(PA13 / PA14),WCH-Link 切 ARM 模式后即 CMSIS-DAP
推荐 IDEMounRiver Studio(必选,XW 扩展压缩指令只有它的工具链支持)Keil MDK 或 MRS 均可
参考手册CH32V:青稞微处理器手册 + 对应 RMCH32F 与 CH32V 的外设章节共用同一本 RM
中断控制器PFIC(快速可编程中断控制器),支持 HPE 硬件压栈与 VTF 免表中断标准 NVIC,16 级嵌套
系统定时器64 位自增型 SysTick(V3A),HCLK/8 时基24 位自减型 SysTick(内核自带),HCLK 或 HCLK/8
不是「换个编译器」那么简单

同一个外设,在 CH32F 上用 CMSIS 的 NVIC_EnableIRQ(),在 CH32V 上要用 PFIC 的 NVIC_EnableIRQ() 同名函数但走完全不同的实现。 沁恒的库函数把两个平台的 API 名字做成了一样的,底下的寄存器操作完全不同。这意味着移植时不能只看能否编译通过, 要确认所选 SDK 分支与目标芯片的内核一致。

2.3 全家族规格速查

下表把 CH32 主流型号的核心资源拉平对比。所有数字取自官网产品页对应 Revision 的特性清单:

型号内核主频SRAMFlash关键外设供电封装
CH32V003青稞 V2A(RV32EC)48 MHz2 KB16 KB1×USART、1×I2C、1×SPI、10 位 ADC、运放比较器、18 IO3.3 / 5 VSOP8 / SOP16 / TSSOP20 / QFN20
CH32V103青稞 V3A(RV32IMAC)80 MHz20 KB64 KBUSB FS Host/Device、16 路 TouchKey、16 路 12 位 ADC、7 定时器、2×I2C、3×USART、2×SPI、7 路 DMA、51 IO2.7~5.5 VLQFP48 / LQFP64M / QFN48X7
CH32V203青稞 V4B(RV32IMAC)144 MHz20 KB64 KB双路 USB FS(1 主/从 + 1 从)、CAN、OPA、10 路 TouchKey、37 IO2.4~3.6 VTSSOP20 ~ LQFP64M 共 9 种
CH32V303青稞 V4F(RV32IMACF)144 MHz64 KB256 KB1×USB FS Host/Device、1×CAN、SDIO、FSMC、DAC、8 串口、10 定时器、80 IO2.5 / 3.3 VLQFP48 / LQFP64M / LQFP100
CH32V307青稞 V4F(RV32IMACF)144 MHz64 KB256 KBUSB HS 480 Mbps(内置 PHY)、USB FS OTG、2×CAN、千兆 ETH(内置 10M PHY)、DVP、SDIO、FSMC、TRNG、80 IO2.5 / 3.3 VLQFP64M / LQFP100
CH32V208青稞 V4C(RV32IMAC)144 MHz64 KB128 KBBLE 5.3(2 Mbps)、10M ETH MAC+PHY、USB FS Host/Device + Device、CAN、53 IO2.4~3.6 VQFN28 / QFN48 / QFN68 / LQFP64M
CH32X035RISC-V4C48 MHz20 KB65 KBUSB PD + Type-C 控制器及 PHY、PIOC 可编程协议 IO、28 KB SRAM 级 DMA 8 路、2 高级定时器、4×USART、14 路 TouchKey2~5.5 VQFN12 ~ LQFP64M 共 7 种
CH32L103RISC-V4C96 MHz20 KB64 KBUSB PD + Type-C PHY、4×USART(LIN/ISO7816)、2×I2C、2×SPI、CAN(部分型号支持 CAN FD)、低功耗定时器、16 外部中断1.8~3.6 VTSSOP20 ~ LQFP48 共 5 种
CH32M007青稞 RISC-V2C48 MHz8 KB65 KB3 Msps 12 位 ADC、高压摆率 OPA、2×CMP、7 路 DMA、内置三相预驱(48 V 双 N / 24 V P+N)、自举二极管与高压 LDO6~48 V / 6~24 VQSOP24 / QFN26C3 / QSOP28 / QFN32
CH32F103Cortex-M372 MHz20 KB64 KB双路 USB FS、CAN、12 位 DAC、16 路 TouchKey、7 定时器、51 IO2.7~5.5 VLQFP48 / LQFP64M / QFN48X7

2.4 通用型:CH32V103 / CH32F103

整个 CH32 货架里最稳的那块砖,也是绝大多数 projects 的默认答案。两者外设几乎一模一样、共用同一本 RM,差别只在内核。

  • CH32V103:青稞 V3A,RV32IMAC,最高 80 MHz。20 KB SRAM / 64 KB CodeFlash,另有 3.75 KB 出厂固化的 BootLoader 区。
  • CH32F103:Cortex-M3,72 MHz。相比 V103 多了一路独立 USB FS Device 与 1 个 CAN 控制器,并带 12 位 DAC。
  • 供电范围 2.7~5.5 V 且 GPIO 与 MCU 同步供电 —— 这意味着它能直接做 5 V 系统里的主控,省掉电平转换,这在同价位 MCU 里并不多见。
  • 封装 LQFP48 / LQFP64M / QFN48X7,与 STM32F103 的封装高度兼容,这也是第 17 章「直接换片」成立的前提。
什么时候选 V103

预算敏感、不需要 5 V 以上到 Case 之外的特殊处理、也不介意用 MRS 开发 —— V103 就是答案。 它的 USB 是 Host/Device 复合,做一个 USB 键盘 / 转串口 / 读卡器时,外围器件数量能压到很低。

2.5 增强低功耗型:CH32V203

V203 的定位是「在不牺牲 144 MHz 性能的前提下把功耗做下去」,官网给出的两个关键数字非常能说明问题:

指标CH32V203说明
待机模式典型电流0.5 μA官网特性清单明确标注,适合纽扣电池长期值守
运行功耗约 52 μA/MHz按 144 MHz 满速估算约 7.5 mA,明显低于同频传统 MCU
主频144 MHz,零等待零等待意味着 Flash 不需要插入等待周期
USB双路 FS(1 路 Host/Device + 1 路 Device)一路做 USB 升级通道、一路做产品功能,互不干扰
调试口两线 SDIPA13 / PA14,与 V103 一致

2.6 互联大容量型:CH32V303 / 305 / 307 / 317

这是 CH32 的旗舰线,青稞 V4F 内核(带单精度 FPU)、144 MHz、最高 256 KB Flash / 64 KB SRAM(V307 系列实际登到更高容量档)。 命名和资源的关系大致是:

  • CH32V303:大容量通用型。1×USB FS Host/Device、1×CAN、SDIO、FSMC、2×DAC、TRNG、8 组串口(3 USART + 5 UART)、10 组定时器。
  • CH32V305:连接型,在 303 基础上增加 USB HS。
  • CH32V307:互联型,USB HS 480 Mbps 内置 PHY + USB FS OTG、千兆 ETH 控制器并集成 10M PHY、2×CAN、DVP 数字图像接口。
  • CH32V317:官方描述为集成 USB HS PHY 与 100M 以太网 PHY 的版本,选型时要按料号核对 DS。
V30x 系列的供电分区与 V103 完全不同

V103 是「VDD 一个电源搞定」,而 V303/305/307 分成 VDD / VIO / VDDA / VBAT 四路: VDD 给部分 IO 与调压器(含 USB PHY、ETH PHY),VIO 决定 IO 输出电平幅度,VDDA 给模拟部分且电压必须与 VIO 相同。 做原理图时这三路不能随便并到一起,详见第 16 章。

2.7 无线型:CH32V208

V208 是「青稞 V4C + BLE 5.3 + 10M 以太网 MAC/PHY」的组合,64 KB SRAM / 128 KB Flash,144 MHz。 它的价值在于用一颗芯片同时解决无线与有线联网:BLE 做配网与近场维护,ETH 做上行回传,中间不需要再加一颗网络协处理器。

2.8 超值型:CH32V003

沁恒用来打 8 位 MCU 市场的产品。青稞 V2A 内核,RV32EC 子集(只有 16 个通用寄存器),48 MHz,2 KB SRAM / 16 KB Flash, 最小封装做到 SOP8,支持单线调试。

V003 的三个硬约束,立项前必须确认

① RV32E 只有 16 个通用寄存器(x0~x15),编译工具链必须配 -march=rv32ec,用普通 rv32i 工具链编译出的镜像跑不起来。
② 2 KB SRAM 极小,任何稍大的全局变量、递归、RTOS 任务栈都要非常克制。
③ V003 的 ADC 是 10 位而不是 12 位,采样精度需求高于 10 位的场景不能选它。

2.9 PDUSB 型:CH32X035 / CH32L103

这两颗的共同点是内置 USB PD 与 Type-C 控制器及 PHY,做快充、PD 诱骗、充电宝、电动工具电池管理时几乎不用外加 PD 协议芯片。

型号主频独有资源典型用途
CH32X03548 MHzPIOC 可编程协议 IO 控制器、2 组高级定时器、8 路 DMA、14 路 TouchKey、4×USART(LIN/ISO7816)PD 充电器、 Type-C 多口快充、带屏显的充电产品
CH32L10396 MHz1.8~3.6 V 宽压、低功耗定时器、CAN(部分型号 CAN FD)、USB PD + Type-C PHY电池供电的便携设备、需要 PD 取电的低功耗终端

2.10 电机专用:CH32M007

一颗把三相栅极预驱做进 MCU 的料。青稞 RISC-V2C、48 MHz、8 KB SRAM / 65 KB Flash,12 位 ADC 采样率高达 3 Msps, 内置高压摆率 OPA 与比较器,支持单电阻 / 双电阻电流采样与 3 通道轮询比较器无感定位。

  • CH32M007K8U7 / CH32M007G8R6:内置 48 V 三相双 N 预驱 + 自举二极管 + 高压 LDO,额定 6~48 V。
  • CH32M007E8:内置 24 V 三相 P+N 预驱 + 高压 LDO,额定 6~24 V。
  • 预驱内含死区控制(防高低侧直通)与欠压保护,这两个都不需要软件兜底。

2.11 料号怎么读

以 CH32V103C8T6 为例,拆解规则如下(沁恒与多数国产 MCU 的命名习惯一致):

字段示例值含义
系列前缀CH32VV = 青稞 RISC-V;换成 F 即 Cortex-M3 同资源版本
系列号103产品线代号,103 为经典通用线
引脚数代码CC = 48 pin,R = 64 pin,V = 100 pin,K/G = 32/28 pin 区间
Flash 容量代码86 = 32 KB,8 = 64 KB,B = 128 KB,C = 256 KB
封装代码TT = LQFP,U = QFN / VFQFPN,P = TSSOP,R = 其它小型封装
温度范围66 = -40 ~ 85 ℃ 工业级;7 = -40 ~ 105 ℃ 扩展级
引脚数代码不是绝对的

不同系列的引脚数 / 封装代码映射不完全一致,比如 CH32V003 的 F4P6 是 SOP8 而 V203 的 F6P6 是 TSSOP20。 下单前一定对照该系列的 DS 选型表,不要跨系列套用这两张表。

2.12 选型决策路径

把上面这些收敛成六个问题的决策树,从上往下问,命中即停:

CH32 家族地图 —— 按内核与定位划分的五大分支同一分支内主管脚兼容,跨分支需要重新评估封装与外设映射青稞 V2 超值CH32V003 / CH32M007RV32EC(V2A) / RV32IMAC(V2C)48 MHz · 单线 SDI · SOP8 起主打 8 位 MCU 替代青稞 V3 / V4 通用CH32V103 / V203 / V208 / V30xRV32IMAC(V3A) / RV32IMACF(V4F)80~144 MHz · 两线 SDIUSB / CAN / ETH / BLE青稞 V4C 连接型CH32X035 / CH32L103RV32IMAC(V4C)48~96 MHz · USB PD + Type-CPIOC 可编程协议 IOArm Cortex-M3 兼容型CH32F103 / CH32F203 / F205 / F20772~144 MHz · SWD · 兼容 STM32F103共同底盘(官方 RM 明确描述的部分)RCC / GPIO / AFIO / EXTI / DMA / ADC / USART / SPI / I2C定时器 / RTC / IWDG / WWDG / CRC / 唯一 ID / 内部温度传感外设地址与行为在 F103 与 V103 上一致,差异只在内核选型第一刀先砍内核:必须用 Arm 生态(Keil + CMSIS-DAP 现成调试器)→ CH32F;否则一律建议 CH32V。第二刀砍连接需求:无特殊接口 → V103/V203;要 USB HS + 千兆 ETH → V307;要快充 → X035/L103。
图 2 · CH32 家族地图:五大分支的内核、主频、调试口与定位

来源:wch.cn 产品页 + CH32xRM V2.0

CH32 选型决策路径 —— 六个问题收敛到一颗料每个判断节点的右侧是落选型,不满足则继续向下走① 必须用 Arm 工具链?判定条件是 → CH32F103 / CH32F203(Keil + CMSIS-DAP 直接可用)② 目标成本 ≤ 1 元、封装要极小?判定条件是 → CH32V003(SOP8 / SOP16 / TSSOP20 / QFN20)③ 要 USB PD / Type-C 快充?判定条件是 → CH32X035 / CH32L103(内置 PD PHY + PIOC)④ 要 USB HS 480 Mbps 或以太网?判定条件是 → CH32V307 / V317(HS+ETH)CH32V208(10M ETH + BLE 5.3)⑤ 是电池供电 / 长时间待机?判定条件是 → CH32V203(待机 0.5 μA,运行 52 μA/MHz)⑥ 通用控制 + 成本均衡判定条件CH32V103 · 80 MHz · USB FS最省事的默认答案终点:以上皆不满足时的默认选型
图 3 · CH32 选型决策路径

补充三条不成文经验:

  • 第一次接触就买 V103 或 V307 的官方评估板,别直接从最小系统板起步。官方板带板载 WCH-Link 电路与排针,能省掉一半接线类故障。
  • 同一产品线内优先选大 Flash 那一档。CH32 各档差价极小,后期发现 Flash 不够的成本远高于差价。
  • 需要量产烧录就先确认有没有 WCH-LinkUtility 的命令行接口,别等到产线上才发现只有 GUI 版本。

3 · 青稞 RISC-V 内核:CH32 的真正差异点

很多人把 CH32V 当成「换了编译器的 STM32」,这在写 GPIO 时没问题,但在涉及时序、中断延迟、RTOS 移植时会付出代价。这一章讲清楚青稞到底改了什么。

3.1 青稞处理器家族

「青稞」是沁恒自研 32 位微处理器的总称,遵循并兼容开放 RISC-V 指令集,在此之上加了若干自定义扩展。官网给出的家族表如下:

型号指令集硬件堆栈级数中断嵌套级数免表中断通道发射宽度流水线向量表模式XW 扩展PMP 区域数
青稞 V2ARV32EC22212地址 / 指令√—
青稞 V3ARV32IMAC22413指令——
青稞 V4ARV32IMAC22413地址 / 指令—4
青稞 V4BRV32IMAC22413地址 / 指令√4
青稞 V4CRV32IMAC22413地址 / 指令√4
青稞 V4FRV32IMACF38413地址 / 指令√4
青稞 V5ARV32IMACBF8427~9地址 / 指令√√8

几个容易被读漏的点:

  • V2A 的指令集是 RV32EC 而不是 RV32I:这是 RV32I 的精简子集,只有 16 个通用寄存器 x0~x15。V003/M007 用的就是这一类,编译选项必须与之匹配。
  • 硬件堆栈级数 = 中断嵌套级数:青稞的 HPE 由硬件内部的栈区实现,级数有限。V3A 只有 2 级嵌套;要做到 8 级必须上 V4F。
  • 免表中断通道数:V2A 只有 2 路,V3A 及以后是 4 路。这决定了你能把多少个最紧急的中断改成 VTF 方式。
  • XW 扩展:V3A 不支持,V4B/V4C/V4F/V5A 支持,在 MRS 里选错内核型号会导致用了扩展指令的代码无法反汇编回来。
  • PMP(物理内存保护):V4A 及以后才有,V2A/V3A 内部甚至没有设计 PMP 单元,做安全分区时不能指望它。

3.2 PFIC 快速可编程中断控制器

PFIC 是青稞替代标准 RISC-V PLIC 的方案,也是它对比经典 RISC-V MCU 最大的工程价值。以 CH32V103(青稞 V3A)为例,官方 RM 给的描述是:

项目CH32F103(Cortex-M3 / NVIC)CH32V103(青稞 V3A / PFIC)
中断总数44 个可屏蔽外部中断 + 10 个内核中断最多支持 255 个中断向量,当前管理 44 个外设中断 + 5 个内核中断
不可屏蔽中断NMI(优先级 -2)2 个:NMI 与 EXC
嵌套能力16 级嵌套,优先级可动态修改2 级嵌套中断进入/退出,硬件自动压栈恢复
快速中断—4 路可编程快速中断通道,可自定义中断向量地址
每通道触发/屏蔽/状态由 NVIC 寄存器统一管理每个中断请求有独立的触发位、屏蔽位、状态位
系统定时器24 位自减型 SysTick,HCLK 或 HCLK/8,优先级 664 位自增型 SysTick,HCLK/8 时基,校准后可用作时间基准
软件复位来源AIRCR 的 bit2 置 1PFIC_CFGR 寄存器 SYSRST 位置 1
256 vs 255:为什么 0x00000000 是保留的

CH32V103 向量表中编号 0 与 1 都标注为「保留」,编号 2 才是 NMI(-2 固定优先级),编号 3 是 EXC(-1)。 编号 12 是 SysTick,编号 14 是 SWI 软件中断,编号 16 开始才是外设中断 —— 所以数据库主动发中断这件事要走 SWI, 熟悉 Cortex-M 的朋友需要对这个编号偏移有心理准备。

3.3 HPE 硬件压栈

标准 RISC-V 进入中断时需要软件执行一堆 sw 指令把 Caller Saved 寄存器存到栈里。青稞把这件事做进了硬件:

  • V2 系列(V003/M007)由硬件自动把 10 个整形 Caller Saved 寄存器(x1、x5、x6、x7、x10~x15)保存到用户堆栈区。
  • 压栈顺序为 x1、x5、x6、x7、x10、x11、x12、x13、x14、x15,SP 自动偏移 48 字节。
  • 异常返回时由硬件自动从用户堆栈区恢复到这 10 个寄存器。
  • HPE 支持嵌套,V2 最大嵌套深度为 2 级。
用了 HPE 就必须成对做两件事

① 必须使用 MRS 或它提供的工具链编译,通用 riscv-gcc 不知道这套机制。
② 中断函数必须使用 __attribute__((interrupt("WCH-Interrupt-fast"))) 声明;
    走软件压栈的普通中断函数则声明成 __attribute__((interrupt()))。
把这两个写反,现象是「中断能进去,但出来后程序跑飞」,极难定位。

3.4 VTF 免表中断

VTF 是在 HPE 基础上再省一步:连中断向量表都不查,直接跳到 ISR 入口。配置方法是:

  1. 先按正常方式配置中断:使能对应中断线、写好中断使能位与优先级。
  2. 写中断号:把该中断的中断号写入免表中断 ID 寄存器 PFIC_VTFIDR 的某一路通道 x。
  3. 写入口地址:把中断服务函数的入口地址写入对应的地址寄存器 VTFADDRRx。
  4. 使能该路 VTF:使能对应通道。
通道数很小,用之前先排优先级

青稞 V2A 只有 2 路 VTF,V3A/V4x 是 4 路。这意味着你最多只能挑选最紧急的 2~4 个中断走这条快车道。 一般留给:电机控制的电流环采样触发、高频脉冲计数溢出、关键的通信超时。

3.5 XW 扩展压缩指令与 WFE

标准 RISC-V 的压缩指令扩展(C)只支持字操作的压缩指令,而嵌入式场景大量出现字节与半字操作。青稞为此增加了八条自定义压缩指令:

类别指令作用
加载类c.lbu / c.lhu压缩形式的无符号字节 / 半字加载
存储类c.sb / c.sh压缩形式的字节 / 半字存储
栈相关加载c.lbusp / c.lhusp基于 SP 的压缩字节 / 半字加载
栈相关存储c.sbsp / c.shsp基于 SP 的压缩字节 / 半字存储

这些指令属于沁恒自定义的 XW 子集,只有 MRS 提供的工具链或它的编译器才知道怎么生成与反汇编。这也是「CH32V 必须用 MRS」这条规矩的技术根因。

WFE 指令是另一个非标准扩展:RISC-V 规范里只有 WFI,没有 WFE(Wait For Event)。青稞的做法是—— 把 PFIC 中系统控制寄存器的特定位置 1,WFI 指令就变成 WFE 行为。这样做的好处是不占用指令编码空间, 保证了与标准 RISC-V 工具链的二进制兼容性,同时满足了蓝牙等低功耗场景对事件等待的需求。

3.6 和 Cortex-M3 的差异对照

如果你是从 STM32 迁移过来的工程师,这张表比任何文字描述都管用:

概念Cortex-M3青稞 RISC-V迁移时的动作
中断控制器NVIC,标准 CMSIS APIPFIC,沁恒提供同名函数的适配实现同名但不同实现,换 SDK 分支
中断优先级抢占优先级 + 子优先级,可分组PFIC_IPRIOR 配置,值越小优先级越高原来 0 最低的习惯要反过来
嵌套16 级V3A 只有 2 级(V4F 8 级)深度嵌套的软件架构必须改名
系统节拍24 位自减,一般配 1 ms64 位自增,HCLK/8RTOS 节拍配置要重算重载值
调试口SWD(PA13 / PA14)两线 SDI(同为 PA13 / PA14)物理连线一致,协议不同
位带操作有真正的外设 / SRAM 位带区没有位带,靠 GPIOx_BSHR/BCR 实现原子置位改用 BSHR/BCR
睡眠指令WFI / WFE / SEV 三条都有WFI + 「把 WFI 变成 WFE」的开关位事件唤醒的写法要改
中断延迟优化末尾连锁 / 迟到抢占,由 NVIC 做HPE + VTF,由软件和 HPE 共同实现关键中断要显式配置 VTF
通用寄存器数R0~R15 + 特殊寄存器V2A 只有 x0~x15,其余 V3A/V4x 为 32 个V003 上写汇编要注意这个
青稞内核的三件法宝:PFIC + HPE + VTF三者共同作用就是一件事:把从中断触发到执行 ISR 第一条指令的延迟压到最短中断请求外设 / EXTI / SysTickPFIC 快速可编程中断控制器· 最多 255 个中断向量· 独立触发 / 屏蔽 / 状态位· 优先级由 PFIC_IPRIOR 定· 中断嵌套由 INTSYSCR 控制普通路径:查向量表从向量表取入口地址再跳转VTF:免表中断4 路 / 2 路通道,直接给入口地址HPE 硬件压栈进入中断时由硬件自动把 10 个Caller Saved 寄存器压入堆栈区x1 · x5 · x6 · x7 · x10~x15SP 自动偏移 48 字节三条路径最终都到达 ISR 第一条指令 —— 差别只在「到达之前花了多少个周期」最慢路径 A:标准向量表 + 软件压栈软件执行压栈指令后才进 ISR较快路径 B:标准向量表 + HPE省掉软件压栈指令的时间最快路径 C:VTF + HPE既不查表也不软件压栈前提:使用 HPE 的中断函数必须用 MRS 工具链编译,并声明 __attribute__((interrupt("WCH-Interrupt-fast")))
图 4 · 青稞内核的 PFIC / HPE / VTF 协作关系与三条中断响应路径

来源:青稞处理器手册 + wch.cn 青稞处理器产品页

4 · 开发环境:MounRiver Studio 安装与配置

CH32 的开发环境是「一次性打包」的 —— MRS 把编译器、下载器、调试器、OpenOCD 全装好了。但正因为装得太「自动」,出问题时反而不知道去哪儿找。

4.1 为什么是 MRS

MounRiver Studio(MRS,官网 mounriver.com)由 MounRiver 团队基于 GNU Eclipse 深度定制,是沁恒官方指定的 RISC-V 集成开发环境。 它同时支持 RISC-V 与 Arm 两类内核 —— 这也是为什么同一个调试器(WCH-Link)要区分 RISC-V 模式与 ARM 模式:MRS 都能带,但得告诉它现在带的是哪一类。

官方对它的定位描述是:提供包括定制版 GCC、宏汇编、链接器、调试器、下载器在内的完整开发资源,免费使用。

能力说明
双核开发同一界面下切换 RISC-V / ARM 目标,自动替换工具链与配置
组件在线更新MounRiver Studio II 支持在线更新 SDK、OpenOCD 等模块
组件发布平台申请账号后可提交自己的组件供其他用户下载(面向方案商的机制)
GUI 设计与代码生成内置可视化代码分析与智能补齐
多种下载方式支持 ISP 等多种下载方式,不局限于自有调试器
在线异常追踪调试时可即时查错

4.2 下载与安装

MRS 的安装包与版本说明在官网 www.mounriver.com 的下载页。安装流程本身是标准 Windows 安装向导,但有四条硬约束:

约束原因违反后的现象
安装路径不能有中文、空格Eclipse 系工具链对路径很敏感,Makefile 传递时会被截断编译时 make: *** No rule to make target,但文件明明在
工程路径同样不能有中文/空格同上,且相对路径计算会失效能新建工程但一按编译就报找不到头文件
不要用带空格的用户目录Windows 用户名是中文时尤其致命(C:/Users/张三/)工具链报奇怪的 No such file
安装时先关杀软或加白名单工具链里大量 .exe 会被误杀装完发现 riscv-none-embed-gcc.exe 不见了
推荐的安装姿势

直接装到 D:/MounRiver/MRS_<版本> 这样的短路径;工程统一放 D:/mrs_workspace/; 如果 Windows 用户名是中文,不要用默认的工作空间位置,手动改到 D 盘。

4.3 工具链构成

装完之后,MRS 目录里实际包含了这些东西 —— 知道它们在哪,出问题时才能救:

组件作用出问题时的判断依据
riscv-none-embed-gcc 系列编译、汇编、链接,沁恒定制版命令行敲 riscv-none-embed-gcc -v 能出版本号
定制 binutils生成 hex / bin / map / lst 文件objcopy / size 是否可用
OpenOCD(WCH 版)调试服务器,认识 WCH-Link 与青稞 SDI能否启动并识别到 WCH-Link
GDB命令行调试能否连上 localhost:3333
WCH-LinkUtility独立烧录工具,可脱离 IDE 使用能否单独完成擦除与下载
Link 固件包WCH-Link 自身的固件,位于 MRS 与 Utility 安装路径下Link 掉固件时用来救砖

4.4 首次启动的配置项

MRS 主界面主要由六块区域构成:菜单栏、快捷工具栏、工程目录空间、工程大纲空间、代码编辑空间、输出显示空间。 切到调试视角后会多出反汇编窗口、变量监控窗口、堆栈与断点窗口、内存与外设窗口。

首次使用建议立刻确认三件事:

  1. 确认工具链路径:偏好设置里看 RISCV 工具链是否指向 MRS 安装目录下的 toolchain/bin,不要让它指向某个系统 GCC。
  2. 确认 OpenOCD 路径:下载调试配置里指向的 OpenOCD 必须是 WCH 版本,社区版 OpenOCD 不认识青稞的 SDI 协议。
  3. 插上 WCH-Link 看设备管理器:Windows 下应识别成 WINUSB 设备。出现黄色感叹号就是驱动没装好,这一步没过后面全是白搭。

4.5 安装阶段最常见的五个坑

现象原因处置
双击 MRS 没反应 / 闪退JDK 缺失或版本冲突;路径有中文确认安装目录下的 jre 完好;把安装目录搬到纯英文短路径
新建工程向导里看不到 CH32 型号组件包没更新成功联网更新一次组件,或手动导入对应 EVT 支持包
编译时报 No such file or directory 但文件在路径含中文/空格,或大小写不一致把工程搬到 D:/mrs_ws/proj 这类路径下重建
make: *** [xxx.elf] Error 1 无其它信息链接脚本与实际 SRAM/Flash 容量不匹配检查 Link.ld 里的 MEMORY 段是否与目标料号一致
设备管理器里 WCH-Link 是未知设备驱动未安装用 WCH-LinkUtility 或官网驱动包重装 WINUSB 驱动
一次安装到底拿到什么 —— MRS 的工具链分层这也是为什么「装一个 MRS 就够了」,而不是 VS Code + 一堆散装工具上层 · IDE 界面基于 GNU Eclipse 深度定制工程管理 / 代码编辑 / 自动补齐 / 可视化分析新建工程向导、组件在线更新、宏定义助手中层 · 编译工具链定制版 riscv-none-embed-gcc宏汇编器 / 链接器 / binutils支持青稞 XW 扩展压缩指令,通用 GCC 不支持下层 · 下载与调试内置 OpenOCD + GDBWCH-Link 驱动 / WCH-LinkUtility图形化下载配置 + 命令行两条路都能走底层 · SDK / 支持包EVT 例程包中的 Core / Peripheralstartup + Link.ld + 系统初始化由组件发布平台在线更新关键认知:MRS 不是「一个编辑器 + 你自己的编译器」,它自带的 GCC 是被沁恒改过以支持 XW 指令的定制版本。
图 5 · MounRiver Studio 的四层工具链构成

来源:mounriver.com + 官方竞赛资料中对 MRS 的描述

5 · 第一个工程:从新建到点亮 LED

这一章的目标非常具体:新建工程、写十行代码、编译通过、下载成功、灯在闪。跑通之后再回头理解原理。

5.1 官方 EVT 例程包结构

每个系列都对应一个 EVT 压缩包(例如 CH32V103EVT.ZIP、CH32V20xEVT.ZIP、CH32V307EVT.ZIP),里面通常包含:

  • 评估板说明书 PDF:板子每个跳线、排针、LED 对应的 IO,第一次上手一定要先看它。
  • EXAM/ 目录:按外设分目录的示例工程(GPIO、USART、SPI、I2C、ADC、TouchKey、USB Device/Host、RTC、低功耗……)。
  • SRC/ 或各工程内的公共层:Core、Debug、Startup、Ld、Peripheral。
  • USB 相关例程:通常会单独给出 CDC / HID / MSC / Host 枚举的完整实现。
先跑一个官方例程,再建自己的工程

不要上来就用向导新建一个空工程。正确顺序是:编译一个官方 GPIO 例程 → 下载 → 看到 LED 行为变化, 这一步能一次性验证「工具链、Link、接线、芯片」四个环节全是好的。之后再把自己代码塞进这个工程里。

5.2 用向导新建工程

MRS 里通过 File → New → MounRiver Project 进入向导。关键选项:

  1. 芯片系列:选中对应的 CH32 系列(例如 CH32V103)。选错会导致启动文件与链接脚本完全对不上。
  2. 具体料号:部分版本要求选到具体型号,例如 CH32V103C8T6 —— 这决定了 Flash/RAM 大小。
  3. 工程模板:选「裸机 + 对应系列」模板,它会自动带出 Core / Startup / Ld / Peripheral 骨架。
  4. 工具链:默认即可,不要手动改成其它 RISC-V 工具链。
  5. 完成后先按一次构建,确认「零改动也可以编译通过」。

5.3 工程目录与关键文件

一个标准工程长成下面这样。真正需要你动手的只有 User/ 里的文件,其余四层是骨架:

官方模板工程的目录结构 —— 改 Makefile 之前先看懂这棵树左四层是必须原样保留的骨架,右侧是需要你自己写的地方工程根/Core/core_riscv.h / core_riscv.c启动牵引:SystemInit、异常入口、PFIC 封装Debug/debug.c / debug.hSDI 打印与 printf 重定向实现Ld/Link.ld链接脚本,决定 Flash / RAM 分布Peripheral/inc/ + src/ 各外设驱动GPIO / USART / SPI / I2C / ADC / TIM ...Startup/startup_ch32v10x.S向量表与复位入口 —— 换型号时必须替换User/main.c / ch32v10x_it.c / conf.h你自己的业务代码与中断服务函数换型号时最小改动集:改 Startup 里的启动文件 + Link.ld 里的 MEMORY + Peripheral 换对应系列驱动
图 6 · CH32 官方模板工程的目录结构与每层职责

5.4 编译与产物

点击构建后,MRS 会在工程的 obj/ 目录产出这些文件:

产物用途什么时候会用到
*.elf带符号表的可执行镜像调试时必须用这个文件,GDB 靠它找源码行号
*.hexIntel HEX 格式发给产线或用第三方烧录器时
*.bin纯二进制镜像做 IAP、OTA、自定义 bootloader 时用
*.map符号地址表查 Stack/Heap 用了多少、函数占用多大
*.lst反汇编列表排查 HPE / VTF 属性是否真的生效
看不到 elf 就别点调试

如果 obj/ 里只有 .hex 没有 .elf,调试器即使连上芯片也会「能下载但不能断点」。 这是 link 阶段失败或构建配置里被勾选了「只生成 hex」的典型症状。

5.5 点亮 LED 的完整代码

下面这份代码是 CH32V103 的最小可运行形态。注意三点:时钟默认是内部 HSI 8 MHz;GPIO 属于 APB2 外设必须开对应时钟; GPIO_WriteBit 走的是 BSHR/BCR 原子寄存器,不存在读-改-写竞态。

#include "debug.h"          // 提供 Delay_Init / Delay_Ms / printf 支持
#include "ch32v10x.h"       // 外设寄存器定义与库函数

int main(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    /* 1. 延时机初始化(基于 SysTick) */
    Delay_Init();

    /* 2. 打开 GPIOA 的时钟 —— APB2 外设,漏掉这行 LED 永远不会亮 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* 3. 配置 PA0 为推挽输出,50 MHz */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    while (1)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_0);      // → BSHR,原子置 1
        Delay_Ms(300);
        GPIO_ResetBits(GPIOA, GPIO_Pin_0);    // → BCR,原子清 0
        Delay_Ms(300);
    }
}

/* 也可以直接用位翻转:GPIOA->OUTDR ^= GPIO_Pin_0; 但那是读-改-写,中断里不能用 */
这一行如果漏了会怎样备注
RCC_APB2PeriphClockCmd(...)LED 完全不亮,但编译器和下载都不报错新手第一大坑,GPIO 都在 APB2 上
Delay_Init()Delay_Ms 的时长完全不对(可能是几百倍误差)它依赖 SysTick 校准
GPIO_Mode_Out_PP选成 GPIO_Mode_Out_OD 时必须外加 pull-up 才有高电平开漏输出不驱动高电平
结构体初始化 = {0}成员是随机值,某些国产库会直接死机MRS 的工程里这条是模板自带的好习惯
跑到这一步的验收标准

① 编译输出里有明确的 text / data / bss 三行数字;
② obj/ 目录下同时存在 .elf 与 .hex;
③ 下载窗口提示成功,且板载 LED 按 300 ms 节奏翻转。
三条全中,说明「工具链 + 下载链路 + 最小系统」全部正常,可以进入第 7 章正式研究下载原理。