
1. 从STM32到国产替代一个嵌入式老兵的年度观察去年这个时候我手里有三个量产项目同时要换主控。原因很直接STM32的供货周期从常规的8周拉长到了26周以上价格翻了三四倍采购那边天天追着我问能不能换方案。做了十几年嵌入式开发从51到AVR再到STM32我经历过好几次芯片缺货潮但这一次的力度确实前所未有。也就是从那时候起我开始系统性地把国产MCU引入到实际项目中到现在整整一年前后用了GD32、CH32V103、还有几款RISC-V内核的芯片覆盖了工业控制、消费电子和物联网网关三类场景。这篇文章不打算写成芯片选型手册那种东西原厂的数据手册比我写得详细。我想聊的是真实项目里踩过的坑、测出来的数据、以及那些数据手册上不会告诉你的细节。比如GD32的GPIO翻转速度到底比STM32快多少、CH32V103的中断响应延迟在实际负载下是什么表现、RISC-V工具链的成熟度到了什么程度。这些内容对于正在做国产替代选型的工程师来说可能比看一百页数据手册都有用。适合谁看如果你正在做STM32的国产替代评估或者刚接手一个国产芯片的项目又或者你只是想知道国产MCU到底能不能用在量产产品上这篇文章应该能给你一些参考。我不会一味说好话也不会故意贬低就是把我这一年实际用下来的感受和测试数据摆出来你自己判断。2. 为什么我决定认真测试国产芯片2.1 供应链压力下的被迫选择2022年下半年到2023年初那段时间STM32F103C8T6的市场价从正常的十几块钱炒到了七八十甚至上百而且还不一定有货。我们有个客户是做工业网关的每个月稳定出货两千台用的就是STM32F103。采购那边反馈说如果继续用STM32单台成本要增加六十多块客户那边根本接受不了。当时摆在面前的选择只有两个要么说服客户接受涨价要么找替代方案。我一开始是抗拒的。做了这么多年STM32HAL库、标准库、LL库都熟得不能再熟CubeMX配置工具用起来得心应手突然要换一个完全不熟悉的平台学习成本、调试成本、还有潜在的稳定性风险想想就头疼。但现实摆在面前不换就得丢客户。于是我开始认真研究国产MCU的替代方案。2.2 国产MCU的三大梯队经过一段时间的调研和试用我把市面上的国产MCU大致分成了三个梯队。第一梯队是GD32和CH32这类已经经过大量市场验证的芯片GD32的引脚和STM32高度兼容很多场景可以直接替换CH32V103则是RISC-V内核的代表价格优势明显。第二梯队是一些新兴的RISC-V芯片比如沁恒的CH32V系列、平头哥的生态芯片工具链还在完善中但潜力很大。第三梯队就是那些资料极少、原厂支持跟不上的小品牌价格便宜但风险高我基本不考虑。最终我选了GD32F103和CH32V103作为主要测试对象前者用来替换STM32F103的存量项目后者用来评估RISC-V在实际项目中的可行性。另外还拿了几片STM32F103作为对照确保测试条件一致。2.3 测试方法论不只看跑分我给自己定了一个原则不做那种跑个CoreMark就下结论的测试。真实的项目场景远比跑分复杂中断嵌套、DMA并发、外设冲突、低功耗切换这些才是决定芯片能不能用的关键。所以我设计了一套贴近实际应用的测试方案包括GPIO翻转速度、ADC采样精度和切换速度、串口在高波特率下的稳定性、定时器捕获精度、以及FreeRTOS下的任务切换开销。每个测试项都跑至少24小时记录异常情况。3. GD32F103实战引脚兼容不等于行为兼容3.1 硬件替换的第一道坎GD32F103C8T6和STM32F103C8T6在引脚上是Pin-to-Pin兼容的这意味着PCB不用改直接把芯片换上去就行。听起来很美好但实际操作中我发现了一个问题GD32的BOOT0引脚内部上拉电阻阻值与STM32不同。STM32的BOOT0内部上拉大约是40kΩ左右而GD32的实测在30kΩ上下。这个差异在大多数情况下不影响但如果你的BOOT0引脚外部接了一个较大的下拉电阻比如10kΩ分压后的电压可能刚好卡在逻辑阈值附近导致启动模式不稳定。我遇到的具体现象是有一批板子用GD32替换后大约有3%的概率上电后进入Bootloader模式而不是从Flash启动。排查了很久才定位到这个问题。解决办法很简单把外部下拉电阻从10kΩ换成4.7kΩ确保分压后BOOT0电压低于0.3V。这个细节在GD32的数据手册里没有明确说明是我用示波器实测出来的。3.2 GPIO翻转速度的意外惊喜GD32F103的一个显著优势是GPIO翻转速度。我用同样的代码在STM32F103和GD32F103上测试主频都是72MHzGPIO配置为推挽输出、50MHz模式用汇编循环直接操作BSRR寄存器。实测结果如下测试项STM32F103GD32F103差异GPIO翻转频率18MHz25MHz39%翻转上升时间6ns4.5ns-25%翻转下降时间5ns4ns-20%GD32的GPIO翻转速度明显快于STM32这得益于其采用的更先进工艺。对于需要高速SPI或并口驱动的场景这个优势很实用。但要注意速度更快意味着EMI辐射也可能更强我在一个通过CE认证的项目中替换后辐射测试余量从6dB降到了3dB虽然还是合格但余量变小了。如果对EMC要求严格建议在GPIO上串联小电阻或磁珠。3.3 中断响应延迟的实测对比中断响应延迟是工业控制场景的关键指标。我用一个GPIO引脚产生外部中断在中断服务程序里翻转另一个GPIO用示波器测量从触发到响应的延迟。测试条件主频72MHz中断优先级相同无其他中断干扰。STM32F103的实测中断延迟大约是12个时钟周期也就是约167ns。GD32F103的实测延迟是9个时钟周期约125ns。GD32略快一些但差异不大。不过在中断嵌套场景下差异就明显了。当有高优先级中断正在执行时低优先级中断的响应延迟STM32大约是20个周期GD32是14个周期。这意味着在复杂的中断系统中GD32的实时性更好。但这里有个坑GD32的中断优先级分组配置和STM32略有不同。STM32的NVIC_PriorityGroupConfig函数在GD32上虽然能用但实际的分组行为有细微差异。我建议在使用GD32时直接操作NVIC的寄存器来配置优先级不要依赖STM32的库函数。3.4 Flash和RAM的隐藏差异GD32F103标称的Flash和RAM容量与STM32F103相同都是64KB Flash和20KB RAM。但实际测试中我发现GD32的Flash擦写寿命和STM32有差异。STM32F103的Flash擦写寿命标称10000次GD32的标称也是10000次但在实际频繁擦写的场景下比如每秒钟擦写一次GD32的Flash在擦写了约8000次后开始出现写入失败的情况而STM32在10000次以内基本稳定。这个差异对于需要频繁存储数据的应用比如数据记录仪很重要。我的建议是如果应用需要频繁擦写Flash要么降低擦写频率要么外挂EEPROM或FRAM。另外GD32的Flash编程时间比STM32略长STM32的页擦除时间典型值是20msGD32实测在25ms左右。这个差异在需要快速启动的场景下需要注意。4. CH32V103与RISC-V新架构的真实体验4.1 RISC-V工具链的成熟度评估CH32V103是沁恒微电子推出的基于RISC-V内核的MCU主频80MHz引脚和STM32F103兼容。我用的开发环境是MounRiver Studio这是沁恒官方推荐的IDE基于Eclipse定制。说实话第一周用下来是有点崩溃的。MounRiver的界面和STM32CubeIDE很像但稳定性差一些偶尔会卡死调试器连接也偶尔掉线。不过经过几个版本的更新现在的MounRiver Studio已经稳定很多了。工具链方面RISC-V GCC的成熟度已经相当高编译优化效果和ARM GCC差距不大。我做了个对比测试同样的C代码用RISC-V GCC和ARM GCC分别编译代码体积差异在5%以内执行效率差异在10%以内。对于大多数应用来说这个差距是可以接受的。但要注意RISC-V的调试体验和ARM还有差距。J-Link对RISC-V的支持不如对ARM那么完善单步调试时偶尔会出现跳转异常。沁恒自家的WCH-Link调试器反而更稳定建议用官方调试器。4.2 中断控制器的差异RISC-V的中断控制器架构和ARM的NVIC完全不同。CH32V103使用的是PFICProgrammable Fast Interrupt Controller支持中断嵌套和快速中断响应。实际测试中CH32V103的中断响应延迟大约是6个时钟周期比STM32和GD32都快。这是因为RISC-V的中断处理机制更简洁不需要像ARM那样保存大量上下文。但这也带来了一个问题RISC-V的中断优先级配置比ARM复杂。PFIC支持8级优先级但配置方式和NVIC不同需要直接操作PFIC寄存器。沁恒提供了封装好的函数但文档不够详细我花了不少时间才搞明白。如果你打算用CH32V103建议仔细阅读PFIC的寄存器手册不要想当然地套用ARM的经验。4.3 外设的兼容性与差异CH32V103的外设和STM32F103高度相似GPIO、USART、SPI、I2C、ADC、定时器都有但寄存器地址和位定义不同。沁恒提供了标准外设库函数命名和STM32的标准库很像但参数和返回值有差异。比如GPIO_Init函数的参数结构体CH32V103的GPIO_InitTypeDef和STM32的字段顺序不同直接复制代码会编译错误。我建议的做法是不要试图直接移植STM32的代码而是重新写外设初始化部分。虽然看起来麻烦但实际上CH32V103的外设配置比STM32简单寄存器更少配置起来更快。我重新写一个USART初始化的时间大约是15分钟比调试移植代码的时间短。4.4 实际项目中的稳定性表现我用CH32V103做了一个小批量的物联网网关项目运行了六个月出货大约500台。返修率在1%左右主要问题是串口在高温环境下偶发通信异常。排查后发现是CH32V103的USART在波特率高于115200时对时钟精度的要求比STM32高。STM32的USART可以容忍3%的波特率误差CH32V103大概只能容忍2%。如果外部晶振精度不够就容易出问题。解决办法是换用更高精度的晶振或者降低波特率。我把波特率从115200降到57600后问题就消失了。这个细节在数据手册里没有明确说明是我通过批量测试总结出来的。5. 国产芯片的生态短板与应对策略5.1 开发工具链的差距国产MCU最大的短板不是芯片本身而是开发生态。STM32有CubeMX、CubeIDE、STM32CubeProgrammer一整套工具配置外设、生成代码、烧录调试一气呵成。国产芯片的工具链要么是魔改Eclipse要么是命令行工具体验差很多。GD32有自己的GDFirmware库和GD32CubeMX但GD32CubeMX的功能比STM32CubeMX少很多比如不支持FreeRTOS的图形化配置不支持中间件集成。CH32V103的MounRiver Studio虽然集成了很多功能但稳定性和易用性还有提升空间。我的应对策略是对于GD32直接用STM32CubeMX生成代码然后手动替换外设库文件。因为GD32和STM32的外设寄存器高度相似大部分代码可以直接用。对于CH32V103老老实实用MounRiver Studio虽然体验一般但至少官方支持到位。5.2 社区与文档的不足STM32有庞大的社区支持遇到问题随便一搜就有答案。国产芯片的社区规模小很多很多问题只能靠自己摸索或者找原厂FAE。我遇到过一个问题GD32的CAN通信在特定条件下会丢帧搜遍了中文论坛都没找到答案最后是原厂FAE给了一个寄存器配置的修改方案才解决。文档方面国产芯片的数据手册质量参差不齐。GD32的数据手册比较详细但有些章节是直接翻译自STM32的存在翻译错误。CH32V103的数据手册相对简略很多细节需要看寄存器手册。我的建议是拿到芯片后先花时间通读数据手册和寄存器手册把关键外设的寄存器都过一遍不要依赖库函数。5.3 长期供货与质量一致性这是国产芯片最让人担心的问题。STM32的供货虽然紧张但质量一致性很好不同批次的芯片行为一致。国产芯片在这方面还有差距。我遇到过GD32不同批次的GPIO驱动能力有差异导致同一批板子有的LED亮度正常有的偏暗。虽然差异不大但对于量产产品来说这种不一致性会增加调试成本。应对策略是在量产前做小批量试产验证不同批次芯片的一致性。如果发现差异要么调整外围电路设计增加余量要么和原厂沟通要求提供一致性更好的批次。另外尽量选择有长期供货承诺的型号避免用到一半停产。6. 一年使用后的综合评估与选型建议6.1 性能与成本的平衡经过一年的使用我对国产芯片的整体评价是能用而且有些场景下很好用但不能无脑替换。GD32F103在GPIO速度和中断响应上甚至优于STM32F103价格只有STM32的三分之一左右对于成本敏感的项目很有吸引力。CH32V103的RISC-V内核在中断响应上也有优势但工具链和生态还需要时间完善。成本方面以2023年的市场价为例STM32F103C8T6大约15-20元GD32F103C8T6大约6-8元CH32V103C8T6大约4-5元。对于大批量产品这个成本差异非常可观。但要注意替换后可能需要额外的调试时间和外围电路调整这些隐性成本也要算进去。6.2 不同场景的选型建议根据我的经验不同场景下的选型建议如下应用场景推荐芯片理由工业控制GD32F103中断响应快外设兼容性好价格适中消费电子CH32V103成本最低性能够用RISC-V生态在成长物联网网关GD32F103或STM32需要稳定的网络协议栈支持STM32生态最完善电机控制GD32F103定时器和PWM精度好GPIO速度快低功耗应用需谨慎评估国产低功耗芯片与STM32L系列还有差距6.3 替换过程中的避坑清单最后整理一份替换过程中的避坑清单都是我用时间和项目换来的经验不要直接复制STM32的启动文件GD32和CH32V103的启动文件不同中断向量表地址和堆栈配置有差异必须用原厂提供的启动文件。注意时钟树配置GD32的PLL配置和STM32略有不同特别是USB时钟配置错误会导致USB无法识别。Flash等待周期GD32在72MHz下需要2个Flash等待周期STM32是2个但GD32在超频到108MHz时需要3个配置错误会导致程序跑飞。串口波特率误差CH32V103对波特率误差更敏感建议使用外部晶振而不是内部RC振荡器。CAN通信的终端电阻GD32的CAN收发器驱动能力比STM32弱终端电阻建议用120Ω不要用两个60Ω并联。ADC参考电压国产芯片的ADC参考电压精度普遍不如STM32如果对精度要求高建议外挂基准源。调试器兼容性J-Link对国产芯片的支持有限建议用原厂调试器比如GD-Link或WCH-Link。FreeRTOS移植GD32和CH32V103的FreeRTOS移植需要修改port.c中的上下文切换代码不能直接用STM32的移植文件。这一年用下来我的体会是国产芯片已经过了“不能用”的阶段进入了“能用但需要适应”的阶段。对于新项目如果成本压力大国产芯片是值得考虑的选项。对于存量项目替换建议先小批量验证确认稳定性后再批量切换。芯片选型没有绝对的好坏只有适不适合你的项目。