第4章:MCU最小系统设计——从一颗光杆芯片到它能跑起来
大家好,前三章老张带着大家把电阻电容、模电调理、数字电平这些基本功夯了一遍。从这一章开始,咱们要动真格的了——设计一块能跑起来的STM32核心板。
很多兄弟用惯了现成的开发板,觉得画核心板没啥难度,照着官方原理图抄就是了。可真到自己动手的时候才发现:晶振要不要加?电容选多大的?复位电路真的需要吗?BOOT引脚怎么接才不翻车?选型表和实际用起来完全两码事。
这一章,我就带你从零开始,画出一块以STM32F103C8T6为核心的最小系统电路。我不光告诉你每个引脚怎么接,更重要的是告诉你为什么这样接,以及接错了会怎样。理解透这一章,以后你换任何一款MCU,都能自己设计出最小系统来。
一、什么是最小系统?三个字说清楚
所谓“最小系统”,就是能让MCU跑起来的最基本外围电路。给MCU供上电,接好三样东西——电源、时钟、复位——然后引出下载口,芯片就能烧程序并且工作了。缺一样都不行。
拿STM32F103C8T6举例,你要画的核心电路就五件事:
供电:把外部电源变成稳定的3.3V,给VDD、VDDA等引脚供上。
时钟:外接一个8MHz晶振给主时钟用,再加一个32.768kHz晶振给RTC用(可选)。
复位:一个按键加上拉电阻,按一下能让芯片重启。
启动配置:BOOT0和BOOT1引脚接对,决定芯片从哪启动。
下载调试口:引出SWD接口,用ST-Link烧程序。
这五样搞定了,单片机就活了。剩下的GPIO、外设,那都是锦上添花。
二、供电电路——MCU的“心脏起搏器”
2.1 电源引脚分布和供电分组
STM32F103C8T6有多个电源引脚,不是随意标的,它们分组供电给芯片内部不同区域:
VDD(3个引脚):给数字核心、IO口、大部分外设供电。接3.3V。
VDDA(1个引脚):给内部ADC、PLL、复位模块等模拟部分供电。也必须接3.3V,而且电压要与VDD保持同步,压差不能超过0.3V。
VSS(3个引脚):数字地,跟VDD对应。
VSSA(1个引脚):模拟地,跟VDDA对应。
VBAT(1个引脚):备份域供电。接3.3V或备用电池,芯片断电时维持RTC和备份寄存器。
每个VDD和VDDA引脚旁边,都必须有一颗0.1μF的去耦电容到地,而且电容离引脚越近越好。原因老张在第1章讲得很清楚:芯片内部晶体管高速开关需要瞬时大电流,这颗电容就是贴在芯片脸前的蓄水池。
另外,VDDA脚附近我习惯加一颗10μF的钽电容或陶瓷电容,提供低频储能;VDD总入口处再来一颗100μF的电解电容做大水池(实际很少用到)。三层滤波,把从电源模块过来的纹波吃得干干净净。
2.2 模拟地与数字地怎么处理?
这个问题争论了很多年。老张直接说我的做法:模拟地和数字地在整板只用一个0Ω电阻或磁珠单点连接,位置放在VDDA和VSSA引脚附近。
为什么要单点接地?数字区域的开关噪声会在地平面上产生压差波动,如果模拟地和数字地到处乱连,数字噪声会串进模拟区域,ADC读数就不干净了。单点接地相当于只开一个门,把数字噪声限制在数字区,不让它去污染模拟信号。
磁珠的话,选100MHz阻抗在几百Ω到1kΩ之间的,滤除高频数字噪声;如果用0Ω电阻,那就纯单点连接,无滤波效果。对ADC精度要求不高的场合,0Ω电阻完全够用。
2.3 VBAT引脚处理
如果你不打算用后备电池,VBAT直接接3.3V即可,省事。如果需要掉电保持RTC时钟,VBAT接一颗CR1220纽扣电池(通过一个二极管做双路切换,主电掉电自动切到电池供电)。二极管用肖特基(如BAT54C),压降小,减少电池消耗。
有个教训:有次我没接VBAT,又恰好主电波动了一下,RTC时间清零了。后来查手册才发现VBAT不但供电RTC,还供着备份域寄存器。哪怕你不用RTC,VBAT也最好接上VDD,防止意外掉电导致某些状态丢失。
三、时钟电路——MCU的“心跳脉搏”
3.1 主时钟晶振:8MHz晶振 + 两个负载电容
STM32内部虽然有RC振荡器,但精度只有1%左右,温度漂移也大。做串口通信、USB、CAN这些需要精确时序的应用,必须上外部晶振。
F103的标准接法:8MHz无源晶振跨接在OSC_IN和OSC_OUT引脚之间,晶振两端各对地接一颗负载电容。
两颗电容的容值怎么选?公式是 C = 2×(CL – Cs),CL是晶振规格书里标的负载电容(常见12.5pF或20pF),Cs是PCB走线和引脚本身的寄生电容(一般估3~5pF)。比如晶振CL=20pF,Cs估5pF,则C=2×(20-5)=30pF,选标称值27pF或33pF都行。要求不高的场合,直接上22pF通用值也能起振。
晶振布局铁律:晶振和两颗电容必须紧靠MCU引脚放置,走线尽可能短,晶振下方不走任何信号线。我见过有兄弟把晶振放在板子边上,引线拉了2cm长,结果起振困难,单片机时而起振时而罢工。原因就是长走线增加了寄生电容和电磁干扰,破坏起振条件。
3.2 RTC时钟晶振:32.768kHz(可选)
如果你需要RTC日历功能,加一个32.768kHz的晶振接在OSC32_IN和OSC32_OUT之间,匹配电容一般选6pF~15pF(参照晶振手册)。
这个晶振更娇气,对走线要求更高。走线长一点、旁边有开关电源、温度变化大都可能导致频偏过大甚至停振。老张的习惯是:不用RTC就直接省掉这颗晶振和两个电容,省BOM省事。需要高精度RTC的场合,干脆用外部RTC芯片(如DS1302),比MCU内置的准得多。
四、复位电路——最不起眼,但不能没有
STM32的复位引脚是NRST,低电平有效。正常工作时要保持高电平,拉低就复位。
最简单的复位电路:一个10kΩ上拉电阻接到3.3V,确保正常工作时NRST为高。再并一个按键到地,按下按键时NRST被拉到低电平,芯片复位(实际项目用100nF电容代替按键即可)。
那个上拉电阻能不能省掉?不行。STM32的NRST引脚内部有一个弱上拉(约40kΩ),按理说可以不上拉。但这个内部上拉比较弱,在电源上电缓慢或者有电磁干扰的场合,NRST可能长时间处于不确定状态,导致MCU上电后不能正常启动。外部加一个10kΩ上拉电阻,电流不大,稳定性提高一大截。
另外,在NRST引脚对地并一颗0.1μF的小电容,能滤掉电源上电瞬间的毛刺,防止误复位。这颗电容与上拉电阻构成RC延时,复位信号会有一个缓慢上升的过程,不用担心边沿触发问题。如果要在NRST和SWD调试器之间串一个电阻(比如100Ω)来保护调试器输出,那这个RC延时就有用了,否则可以不加这颗电容。
地弹场景补充:当很多输出同时从高翻低时,地线瞬间大电流可能让芯片内部地电位轻微抬高,相当于NRST对地电压被拉低,如果这个压差吃掉噪声容限,可能引发误复位。所以电源和地去耦做扎实,也是在保护复位信号的稳定。
五、启动配置——BOOT0和BOOT1接错了烧不进去程序
F103有BOOT0和BOOT1两个引脚,决定芯片上电后从哪启动:
| BOOT1 | BOOT0 | 启动模式 |
|---|---|---|
| X | 0 | 从用户Flash启动(正常运行模式) |
| 0 | 1 | 从系统存储器启动(出厂Bootloader,用于串口烧录) |
| 1 | 1 | 从SRAM启动(调试用,极少用) |
常规用法:BOOT0通过一个10kΩ下拉电阻接地,BOOT1任意(默认下拉,跑用户程序)。这是最正常的模式,上电就从你烧进去的固件启动。
进串口ISP烧录:把BOOT0拉高(跳线帽或按键),然后复位,芯片就从系统Bootloader启动,可以用串口烧程序。烧完把BOOT0恢复接地,再复位一次就跑新程序。
有个让很多新手抓狂的问题:画板时BOOT0浮空,结果芯片有时能跑有时不能跑,烧录器也时灵时不灵。原因就是BOOT0悬空后电平不确定,可能被干扰拉高进入ISP模式。所以BOOT0和BOOT1永远不要悬空,一定要有确定的电平,哪怕内部有弱下拉也要外部加固。上电瞬间IO状态未稳定时,靠外部电阻确保电平确定,下拉电阻接地或通过跳线选择接高接低,保证它的电平是确定的0或者1。
补充说明:PB2/BOOT1引脚上电后默认被内部下拉,如果你用不到它来配置启动模式,正常接外设就行,不需要额外处理,当然,除非不得已,特殊引脚一定要慎用。
六、下载调试口——SWD三根线就够了
F103支持JTAG和SWD两种调试接口。JTAG要5根信号线,SWD只要2根(SWDIO、SWCLK)加1根地线和1根可选的复位线,省引脚省空间,我全部项目都用SWD。
标准SWD接口引出4个脚:
SWDIO:数据线,双向。
SWCLK:时钟线,调试器输出。
GND:地线,必须接,不然信号没有参考。
NRST:可选,接目标芯片复位脚,调试器可以硬件复位芯片。
SWDIO和SWCLK各自接一个10kΩ上拉电阻到3.3V,保证在没有调试器连接时电平确定,不会因为悬空而误触发内部调试逻辑。
走线要求:SWD两根信号线不要太长(最好不超过15cm),周围不要紧挨着大电流走线或开关电源。遇到过一个故障:SWD线旁边就是DC-DC电感,调试时经常莫名断开,示波器一看SWCLK上叠加了高频噪声,把电感移远就恢复了。
一个小技巧:SWD的这两根引脚可以复用为普通GPIO(F103里是PA13和PA14)。但一旦复用为GPIO,你就没法用SWD调试了。所以设计时尽量用其他GPIO,把这两个脚留给调试。实在管脚不够用了,可以在代码启动后把这两个脚设成GPIO,但要做好心理准备:以后调试这板子就只能用串口ISP烧录了。另外注意,如果代码一启动就把SWD引脚改掉,那调试器会立刻断开,调试失败。所以一般会在main函数开头加个几百毫秒的延时,再切换引脚。
七、完整原理图速览
把上面五个部分拼起来,就是你第一块STM32核心板的完整最小系统原理图了。老张给你用文字画个信号连接总表checklist(你画原理图时可以按这个检查):
| 模块 | 关键连接 | 注意点 |
|---|---|---|
| 电源 | VDD×3接3.3V,VDDA接3.3V,VBAT接3.3V;每脚一颗0.1μF | VDDA与VDD压差<0.3V |
| 地 | VSS×3接GND,VSSA接GND;AGND与DGND单点连 | 用0Ω或磁珠隔离 |
| 时钟 | OSC_IN/OUT接8MHz晶振+两22pF电容到地 | 晶振靠芯片,下方不走线 |
| 复位 | NRST上拉10kΩ到3.3V,按键到地,并0.1μF | 上拉不能省 |
| 启动 | BOOT0下拉10kΩ到地,BOOT1默认下拉 | 不浮空! |
| 调试 | SWDIO/SWCLK各上拉10kΩ,引出4针接口 | 走线远离功率器件 |
这就是一块能独立工作的MCU核心板最小电路了,加上LDO稳压电源从外部供电(比如USB 5V经过AMS1117-3.3变成3.3V),板子就能跑。但LDO选型和外围电容配置这里先不展开,我会在电源电路章节详细说。
八、常见翻车点总结
我把自己和身边朋友在设计最小系统时踩过的坑,归纳成一张表,建议你每次画完原理图对着自查一遍:
| 翻车点 | 现象 | 原因 | 预防 |
|---|---|---|---|
| VDD去耦电容离芯片太远 | 高频运行不稳定,死机 | 瞬时电流供不上 | 电容紧贴引脚 |
| VDDA没接或接错电压 | ADC读数完全不准,漂移大 | 模拟部分供电异常 | VDDA=VDD=3.3V |
| 晶振电容选错或不匹配 | 起振困难,串口乱码 | 负载电容与晶振不匹配 | 按公式算,留余量 |
| BOOT0悬空 | 芯片随机进ISP模式,不跑程序 | 悬空电平不确定 | 必须下拉或跳线 |
| NRST没上拉 | 上电不启动或随机复位 | 内部弱上拉扛不住干扰 | 外部加10kΩ上拉 |
| SWD引脚被占用 | 能烧程序但无法调试 | 代码启动后把SWD复用了 | 非必须别占用PA13/PA14,或加启动延时 |
| VBAT没接 | RTC不工作,备份域丢失 | 备份域没供电 | VBAT=VDD |
| 模拟地数字地没分 | ADC噪声大,跳得厉害 | 数字噪声串入模拟区 | 单点接地 |
| 晶振下方走信号线 | 时钟抖动,通信出错 | 晶振信号耦合到其他走线 | 晶振下方禁走线 |
| 晶振离MCU太远 | 不起振或频率漂移 | 寄生电容过大 | 紧靠芯片放置 |
九、本章总结
这一章咱们把MCU最小系统的五脏六腑都拆解了一遍:供电、时钟、复位、启动配置、下载口,每根线为什么这么接,不这么接会有什么后果,都讲清楚了。这五样东西是所有嵌入式板卡的共同骨架,以后再画任何一款MCU的板子,万变不离其宗。
