做嵌入式开发这么多年,我一直觉得亲手画一块最小系统板,是吃透一颗单片机最有效的方式。这次就完整记录一下我用STM32F103RCT6设计最小系统板的全过程,从最初的需求分析、原理图绘制,到PCB布局布线,再到打样焊接和上电调试,每一步都会讲到。
STM32F103RCT6是ST的中端主力型号,Cortex-M3内核,主频最高72MHz,256KB Flash,48KB SRAM,采用LQFP64封装。相比大家更熟悉的C8T6,它的Flash翻了好几倍,引脚也更多,能做不少复杂的事情,比如带编码器做电机FOC、同时跑多个串口、做简易USB设备等。如果你正在学STM32,或者想给自己做一块能长期用的下载调试板,自己画一块RCT6最小系统板,性价比非常高。
这篇文章适合刚入门、想动手画第一块板子的同学,也适合已经做了几块板、却老被“下载失败”、“跑不起来”折磨的朋友。我会把原理图里每个电阻电容为什么这么接、PCB上哪些走线必须注意、调试时踩过的坑全部整理出来,尽量让看完的人能一次做成功。
1. 项目概述与整体设计思路
1.1 为什么选STM32F103RCT6,而不是C8T6或ZET6
先聊选型。STM32F103系列大家都很熟,但具体型号之间的差异还是要搞清楚。C8T6只有64KB Flash和20KB SRAM,跑个小灯、串口、简单传感器没问题,一旦要上RTOS、做电机FOC控制,或者用文件系统存点数据,Flash和内存就不够用了。
RCT6的Flash是256KB,SRAM是48KB,在LQFP64封装里算是顶配。相比RBT6的128KB Flash,RCT6多了一倍Flash,价格却只贵几块钱。相比ZET6的LQFP100,RCT6引脚虽然少了,但大多数项目用不到那么多IO,64脚已经足够,而且布线、焊接难度都低了不少。
我这次选RCT6,主要是三个考虑:一是有足够的Flash跑RTOS和中间件,二是LQFP64封装在2层板上就能轻松布通,三是这个型号的货源和价格都稳定,不管以后做产品原型还是搞学习板,都不用担心断货问题。如果你只是入门练手,C8T6也够用,但既然自己画板,一步到位上RCT6更省心。
1.2 最小系统板到底包含哪些部分
很多新手会问,最小系统板到底“最小”到什么程度?严格说,只要能让芯片正常跑起来、并能下载程序,就是最小系统。我理解的最小系统板,必须包含下面五个部分:
- 电源电路:提供稳定的3.3V,并在每个电源引脚附近放置去耦电容。
- 时钟电路:外部8MHz晶振和负载电容,提供准确的高速时钟。内部HSI虽然能跑,但精度差,串口波特率容易飘。
- 复位电路:NRST引脚接上拉电阻和复位电容,实现稳定的上电复位和手动复位。
- 启动模式配置:BOOT0引脚电平决定从Flash还是SRAM启动,设计时把BOOT0下拉到地,强制从主Flash启动。
- 下载调试电路:SWD接口,只用SWDIO、SWCLK、GND和3.3V四根线,就能完成烧录和在线调试。
除了这些,我还会加上电源指示灯、用户LED和按键,把全部IO用排针引出来。这样板子做好后可以直接用来做各种实验,不用再外接一堆飞线。
1.3 方案取舍:LDO还是DC-DC、晶振、调试接口
设计开始前,有几个方案需要定下来,每个选择都会影响后面的调试体验。
电源部分,最小系统板功耗很低,用LDO就足够了。我选了AMS1117-3.3,便宜、到处能买到,从USB的5V降到3.3V,压差1.7V,输出电流800mA左右,对最小系统板绰绰有余。如果做电机驱动板,动力部分需要单独用DC-DC,但数字逻辑部分还是推荐LDO,纹波小,调试时能少很多莫名其妙的问题。
时钟部分,STM32内部有HSI(8MHz)和LSI(约40kHz),理论上不接外部晶振也能跑。但HSI精度不高,温度变化时误差更大,一用到串口通信,波特率就对不上。所以外部HSE晶振是必须的,我用最常见的8MHz无源晶振,配两个20pF负载电容。
调试接口部分,现在主流是ST-Link、J-Link和DAP-Link,都支持SWD模式。SWD只需要两根数据线(PA13/SWDIO、PA14/SWCLK),比JTAG省IO、省空间。我的做法是把SWD和串口都留在板子边缘,调试器接SWD,数据观察接串口,两边不冲突。
2. 原理图设计:每个元器件都有存在的理由
2.1 电源电路的设计与电容选型
电源电路是整块板子的命脉。STM32F103RCT6有多个VDD引脚,每个VDD附近都要放一颗100nF去耦电容,这一点不能省。很多板子偶尔死机、ADC数据跳变,往往就是因为某颗去耦电容离VDD太远。
我画原理图时,电源部分这样安排:
- 输入5V经过AMS1117-3.3,输入端放一颗10uF钽电容和一颗100nF陶瓷电容,输出端放一颗10uF钽电容和一颗100nF陶瓷电容,保证电源稳定。
- 3.3V输出分成多路,分别接到芯片各个VDD引脚,每个VDD就近放100nF,芯片附近再放一颗4.7uF做整体储能。
- VBAT引脚如果需要RTC备用电池功能,接3.3V或纽扣电池,不需要就统一接3.3V。
再说电容选型。陶瓷电容选X7R或X5R材质,耐压16V或25V就够。不要用Y5V,温度特性太差,容量会随温度明显缩水。钽电容注意耐压,5V输入的位置用10uF/10V或16V都行,钽电容极性反接会烧,焊接时一定看清丝印方向。
还有一点要提醒:AMS1117这类LDO对输出电容有要求,输出端最好有10uF以上电容,否则在负载突变时可能振荡。实测下来,输出端放10uF钽电容后,3.3V纹波非常干净,芯片运行稳定性明显提升。
2.2 HSE时钟电路:8MHz晶振与负载电容计算
时钟电路是整块板最容易被忽视、又最容易翻车的部分。STM32F103用外部HSE作为系统主时钟来源,晶振不起振或频率不准,程序根本不执行,或者串口乱码。
8MHz无源晶振需要两个负载电容,典型值18pF到22pF,我一般直接选20pF。负载电容的计算公式是:
CL = (C1 × C2) / (C1 + C2) + Cparasitic
Cparasitic是PCB走线和引脚寄生电容,通常取2到5pF。两颗电容都用20pF,算上约4pF寄生电容,等效负载大约14pF,正好匹配大多数8MHz晶振的标称负载电容。
原理图上,晶振接在OSC_IN(PD0)和OSC_OUT(PD1)两个引脚上,两个负载电容分别从晶振两端下拉到地。这里有个关键经验:晶振正下方不要走任何信号线,周围铺一圈地,能明显减少噪声干扰。
注意:晶振两条走线不要平行拉太长,负载电容要就近接地,晶振正下方尽量不要布置其他信号线。
如果要做RTC功能,还需要32.768kHz晶振接在PC14和PC15上,同样配两个负载电容,通常选6pF到12.5pF,具体按晶振规格来。不用RTC的话,这两个引脚可以当普通IO用。我这块板子做了RTC功能,因为不少项目需要时间戳。
2.3 复位电路与启动模式配置
复位电路看起来简单,但设计不好会出现“上电时程序不稳定”的毛病。NRST引脚内部虽然已有上拉电阻,外部依然要处理。
我的设计是:NRST引脚接10K电阻上拉到3.3V,再接100nF电容下拉到地,同时并联一个按键到GND。上电瞬间电容充电,NRST保持一段低电平,充满后变高电平,芯片退出复位,实现稳定上电复位。按键按下拉低NRST,实现手动复位。
启动模式是新手容易忽略的点。STM32的BOOT0和BOOT1决定复位后从哪启动,组合方式如下:
| BOOT0 | BOOT1 | 启动区域 |
|---|---|---|
| 0 | x | 主Flash(正常运行) |
| 1 | 0 | 系统存储器(串口ISP下载) |
| 1 | 1 | SRAM(调试用) |
最常用的就是从主Flash启动,所以BOOT0通过10K电阻下拉到地,BOOT1虽然正常启动时不参与,我也同样下拉到地,避免悬空。很多方案说BOOT1可以不接,但从严谨角度,所有输入引脚都应有确定电平,全部下拉更稳妥。
2.4 SWD下载调试接口与其他必要外设
下载调试接口是每天都要用的,设计时必须放在好插拔的位置。SWD只需要四根线:3.3V、SWDIO(PA13)、SWCLK(PA14)、GND。我建议做成2.54mm间距的4Pin排针,排成一列,顺序是3V3-SWDIO-SWCLK-GND,用杜邦线或直接插ST-Link转接头都方便。
需要特别提醒的是,SWDIO和SWCLK复用为PA13和PA14。如果你把这两个引脚当普通IO用,就没法用SWD下载了。有些项目把这两个脚接去控制别的东西,结果芯片“变砖”,其实只是SWD被占用。
除了核心下载调试,我还在板子上加了几个“标配外设”:
- 电源指示灯:LED串联1K电阻接到3.3V,判断供电是否正常。
- 用户LED:接PC13,串联330欧姆限流电阻接地,用来跑第一个点灯程序。
- 用户按键:接PA0,另一端接GND,内部上拉时按下为低电平,用于中断实验。
- 排针引出:除电源和地外,把剩余IO尽量引到两排2.54mm排针上,方便后续扩展。
LED限流电阻取值也有讲究。STM32的GPIO输出高电平为3.3V,普通红色LED压降约1.8V到2.0V,按1mA到5mA电流计算,电阻取330欧姆到1K欧姆都行。我板子上两颗LED,一颗用1K更省电,一颗用330让灯更亮,测试不同状态刚刚好。
3. PCB布局布线与打样焊接
3.1 布局思路:让每一颗电容都待在应该待的地方
原理图画完,接下来是PCB布局。我用的工具是立创EDA,免费,元件库封装库很全,画完原理图直接导入PCB,剩下的就是考验耐心的布局环节。
布局第一原则:以MCU为中心,按功能模块分区。我把STM32F103RCT6放在板子正中间,四边留走线空间,晶振紧挨OSC_IN和OSC_OUT引脚,去耦电容单独排成一行,每颗都放在对应VDD引脚旁边。电源输入和LDO放板子边缘一角,让电源从板边进入后快速分布到各个VDD。
具体布局几步说清楚:
- 把MCU固定到板子中心,标注1脚和丝印方向。
- 在MCU四周摆所有100nF去耦电容,一个VDD对应一颗,电容地端尽量靠近MCU的地引脚。
- 晶振放OSC_IN和OSC_OUT中间,两颗负载电容放晶振两端,尽量短走线。
- LDO放板子一角,输入输出电容围绕LDO摆,注意输入输出顺序别反。
- 排针围在板子四边引出IO。
- LED、按键放板边,好按好看。
我第一次画板犯过最蠢的错误,就是把去耦电容放在“看起来整齐”的位置,结果走线绕了很远,实际效果大打折扣。后来我都是“电容贴在引脚旁,地脚对准VDD”,这条经验放在任何板子设计里都通用。
3.2 布线要点:晶振走线、地平面与电源线宽
布局完成进入布线。对STM32F103RCT6最小系统板,2层板完全够用,但有几条布线要求必须遵守。
电源线要粗。3.3V网络我习惯用20mil到30mil,地线同样宽甚至更粗。AMS1117输入端的5V线也用20mil以上。电源线太细,电阻大会引起压降,芯片切换负载时电压跌落,可能导致复位重启。
地线处理上,2层板我习惯顶层走信号线,底层铺一整片地铜,网络设为GND。这样每颗去耦电容的地端都能就近打过孔到底层地平面,回流路径最短,EMI好。如果空间允许,顶层空余区域也铺地铜,再打一排过孔连接上下地层,相当于“跨层网格地”。
晶振走线是重点照顾对象。晶振到MCU的OSC_IN/OSC_OUT尽量短,不要走直角,走45度或圆弧。晶振正下方底层不要走任何其它信号线。两颗负载电容的接地端共用一小块铜皮,再打过孔到地平面,减小地回路面积。
SWD的SWDIO和SWCLK不需要特别处理,但也不要拉太长,3cm以内都可以。复位信号线同样走短。LED、按键这些低速信号没太多讲究,保持合理间距就行。
工艺参数上,我习惯设最小线宽10mil,最小过孔外径24mil、内径12mil,这在立创免费打样工艺限制内完全可制造。4层板当然更好,但2层板做这种小板已经足够,还能省打样费用。
3.3 打样、焊接与焊后检查
PCB设计完成后,导出Gerber上传打样平台。我用的是嘉立创免费打样,5cm×5cm以内都免费,RCT6最小系统板尺寸小,完全在范围内。我设计的板子是5cm×4cm,四角加3mm螺丝孔,方便固定。
打样回来就是焊接。LQFP64引脚密,建议用拖焊法。先在焊盘上均匀涂助焊剂,芯片对准放正,用烙铁固定对角两个引脚,然后沿引脚方向拖锡。锡会顺着助焊剂均匀铺在引脚上,如果连锡也别慌,用吸锡带把多余锡吸掉。
焊接顺序上,我习惯先焊电源部分,再焊晶振电路,接着焊MCU,最后焊排针、LED和按键。这样先不装MCU就能上电测3.3V对不对,如果电源有问题,不会波及芯片。
焊完别急着上电,先用万用表检查几个关键点:
- 3.3V和GND之间是否短路,阻值是否异常,接近0说明有连锡或电容反接。
- 每个VDD引脚到地电容是否正常。
- 晶振两脚之间是否短路。
- SWD的3.3V和GND是否正常。
每次焊完,我都会用放大镜过一遍所有引脚,重点看LQFP64相邻引脚之间有没有锡桥。这一步成本很低,但能省下大量排查时间。
4. 上电调试与常见问题排查
4.1 上电前检查与最小系统验证
焊接完成、静态电阻检查通过后,就可以上电了。但“上电”不是直接插USB线,而是逐步推进。
我的做法是:先用稳压电源设定5V、限流100mA,接到板子VIN和GND。如果电流接近0,至少说明电源输入端没有明显短路。然后看板上电源指示灯亮不亮,再量3.3V输出是否在3.3V±0.1V范围内。确认正常后,关电源,再正常插USB供电。
第一次上电后别急着下载,先做最小系统验证。按一下复位键再松开,用万用表量NRST,正常应该能看到一个上升沿。再用示波器量OSC_OUT,能看到8MHz时钟波形,幅度大约1V到3.3V之间。没示波器的话,直接接ST-Link尝试软件连接芯片,能识别IDCODE,说明芯片已经在工作状态。这是最常用的验证手段。
4.2 Keil工程配置与下载调试
接下来配置下载调试环境。我用Keil MDK,调试器是ST-Link V2,便宜稳定。第一次使用要配置以下内容:
- Options for Target中,Debug选项卡选择ST-Link Debugger。
- 点击Settings,确认能识别SWDIO和SWCLK的IDCODE,器件型号正常。
- Utilities选项卡同样选择ST-Link,Flash Download设为Erase Full Chip加Program,下载前擦除整块Flash。
- 芯片型号选STM32F103RCT6。
- 使用标准外设库时,宏定义要设成STM32F10X_HD,因为RCT6属于高密度产品。
关于固件库,这里多说一句。STM32F103按Flash容量分为低密度、中密度、高密度,RCT6有256KB Flash,属于高密度,宏定义必须用STM32F10X_HD,否则很多外设驱动编译不过或者运行异常。HAL库的话,型号选对、时钟配置对就行。
下载完成后,先跑最简单的点灯程序。第一个程序通常是初始化PC13为推挽输出,主循环翻转电平,让LED一亮一灭。如果LED正常闪烁,就说明电源、时钟、复位、Flash启动、SWD下载全部正常,整块板子基本算调试通过了。
调试时想看结构体变量、数组内容,Keil的Debug模式可以直接看。打开View菜单里的Watch窗口,把变量加进去,如果没自动更新,点击View > Periodic Window Update,开启周期性刷新,就能实时看到变量变化。这个功能新手经常忽略,其实非常好用。
4.3 常见问题速查表与经验总结
实际调试中,我积累了一些高频问题的排查经验,整理成速查表,方便对照:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 上电后电源指示灯不亮 | 电源接反、AMS1117损坏、输入输出引脚焊错 | 先量VIN电压,再量LDO输出 |
| 3.3V对地短路 | MCU引脚连锡、电容焊反、钽电容极性接反 | 断电用万用表蜂鸣档量3.3V到GND阻值 |
| 晶振不起振 | 负载电容错、晶振焊歪、晶振质量差 | 示波器看OSC_OUT,或用HSI启动测串口 |
| SWD下载报No Target connected | SWDIO/SWCLK接错、目标板没供电、PA13/PA14被占用 | 核对四根线,确认3.3V,按住复位键再点下载 |
| Flash Download failed | Keil里Flash容量配置错、芯片型号选错 | 确认型号是F103RCT6,Flash大小256KB |
| 程序跑飞或不稳定 | 去耦电容缺失、电源纹波大、复位电路没做好 | 检查每个VDD的100nF电容,换稳定电源 |
| 串口乱码 | 主时钟频率不对、波特率不匹配、用了HSI | 确认晶振是8MHz,检查系统时钟配置为72MHz |
这些坑我基本都踩过,最常见的就是SWD下载报No Target connected。我后来总结出一个几乎百试百灵的办法:在Keil里点下载按钮的同时,用手指按住板子复位键不放,等进入下载过程再松开。原因是目标芯片可能在复位或Flash擦除期间没正常响应,复位释放瞬间SWD能强制接管。
提示:SWD连不上时,先试试按住复位键再点下载,这是我屡试不爽的招。
再说一个调试技巧。如果程序写坏了时钟配置,芯片进不了main函数,SWD很难连上。这时候把BOOT0跳线设到高电平,让芯片从系统存储器启动,此时SWD依然能连接芯片,再重新擦除、下载正确程序,就能把“砖头”救回来。
串口调试方面,我一直用SSCOM这类串口助手。注意串口助手的波特率要和程序配置一致,另外如果程序用了HSI而不是HSE,串口波特率可能有2%到5%误差,表现为大部分时间正常、偶尔乱码。排查时先确认系统时钟来源。
调试最后,我习惯做一轮老化测试:让板子连续跑LED闪烁程序24小时不断电。如果24小时内没死机、没乱码,这块板子基本可以信任了。办法虽然土,但确实能暴露不少偶发问题。
最后再分享一点个人体会。自己画最小系统板,真正的收获不在于那块板子本身,而在于整个流程走完后,你对芯片的认识完全不一样了。原理图上每一条线、每一颗电容你都清楚来龙去脉,后面再做带电机驱动、传感器采集的复杂板子,心里特别有底。
如果你准备动手,我的建议是第一块板子别追求一次到位,先按最基本的五大部分画一个能跑起来的板子,调试通过之后再考虑加USB转串口、SD卡座、CAN收发器这些功能。一步步来,踩坑也是积累。
我目前这块RCT6最小系统板已经用了大半年,跑过裸机程序、FreeRTOS,还有带编码器的电机FOC控制,表现都挺稳定。下次我计划基于它做一个带CAN总线的评估板,到时候再来分享新的调试心得。