3.3 最小系统电路与上电时序 前两节一直在软件里摸寄存器,这一节退后一步看硬件:芯片要"活"起来,硅片外必须有哪几个元件撑着?LED 限流电阻的阻值是怎么算出来的?按下复位键的那一瞬间,芯片内部经历了什么?这些内容看似偏电,实则直接决定"程序为什么有时不生效"——很多软件悬案的最后现场都在电路上。 最小系统:让芯片活起来的六件套 STM32F103 的最小系统由六个部分组成,市售的蓝药丸板全数具备,认识它们是排障的基本功: 部件 | 元件 | 作用 | 缺了会怎样 供电 | 3.3V 稳压 + 去耦电容 | 提供稳定的 2.0-3.
前两节一直在软件里摸寄存器,这一节退后一步看硬件:芯片要"活"起来,硅片外必须有哪几个元件撑着?LED 限流电阻的阻值是怎么算出来的?按下复位键的那一瞬间,芯片内部经历了什么?这些内容看似偏电,实则直接决定"程序为什么有时不生效"——很多软件悬案的最后现场都在电路上。
STM32F103 的最小系统由六个部分组成,市售的蓝药丸板全数具备,认识它们是排障的基本功:
| 部件 | 元件 | 作用 | 缺了会怎样 |
|---|---|---|---|
| 供电 | 3.3V 稳压 + 去耦电容 | 提供稳定的 2.0-3.6V 电源 | 芯片不启动或随机复位 |
| 时钟 | 8 MHz 晶振 + 两只 20 pF 负载电容 | 提供 HSE 时钟源 | HSE 起振失败,PLL 无法锁定 |
| 复位 | 10 kΩ 上拉 + 100 nF 电容 | 上电缓升保证可靠复位,手动复位按键 | 上电竞态、偶尔跑飞 |
| BOOT 选择 | BOOT0 接地电阻 | 决定从哪启动(Flash 或串口下载) | 启动到 bootloader,程序不跑 |
| 烧录口 | SWD 四线(SWDIO/SWCLK/3V3/GND) | 程序下载与调试 | 只能靠串口慢速烧录 |
| 指示 | 电源 LED、用户 LED | 状态可视 | 排障全靠猜 |
其中最容易被小看的是去耦电容:每颗 VDD 引脚旁的 100 nF 陶瓷电容。芯片内部电平翻转瞬间会从电源抽取脉冲电流,走线电感会让电源瞬间塌陷,去耦电容就在引脚旁就近放电补坑。少了它们,症状是"单独跑正常,一接外设就随机复位"——电源完整性问题穿着软件的外衣出现。
LED 不是电阻,它是二极管:正向导通后有约 2 V 的压降(红黄约 1.8-2.0 V,蓝白约 3.0-3.2 V),且导通后电流对电压极其敏感,必须用串联电阻把电流限定在安全值。计算就一步欧姆定律:
R = (V源 − V_led) / I_led 例:3.3V 的 GPIO 推挽输出,红色 LED 压降 2.0V,目标电流 8 mA R = (3.3 − 2.0) / 0.008 = 162.5 Ω → 取标称值 220 Ω(留裕量) 普通指示用途 I 取 5-10 mA 足够亮;STM32 单引脚上限 25 mA, 但整块芯片总电流上限约 150 mA,多路点亮时要合计。
另一个必懂的概念是推挽与开漏的取舍。推挽输出(3.1 节配的 CNF=00)高电平能主动拉到 3.3 V、低电平主动拉到地,驱动 LED 毫无压力;开漏输出(CNF=01)只能拉低,高电平靠外部上拉实现。开漏的价值在"线与"和电平转换:多个设备把输出线连在一起不会打架(第 5 章 I2C 总线正是靠开漏 + 上拉工作的),外接 5 V 上拉还能让 3.3 V 芯片驱动 5 V 器件的输入。看到"高电平驱动不动、需要 5 V"的需求,就该想起开漏。
按下电源开关之后、main 函数第一行之前,芯片经历一条精确的链条,把它完整走一遍(细节在第 7 章启动流程里升级为软件视角):
用 C 视角复核第 2 步:向量表开头两个字,恰好对应启动文件里的这两行:
/* startup_stm32f10x.s 的等价 C 表达(真实文件是汇编)*/ __attribute__((section(".isr_vector"))) const void *vector_table[] = { (void *)0x20005000, /* 字 0:初始栈顶 = SRAM 末尾 20KB 处(0x20000000 + 0x5000)*/ (void *)Reset_Handler, /* 字 1:复位入口,内核上电第一跳 */ /* 之后依次是 NMI、HardFault、EXTI0_IRQHandler …… 每个中断一个槽位 */ };
这也回答了一个悬案:为什么中断服务函数的名字写错一个字母,程序就在中断触发时跑飞——名字是向量表的槽位指针,写错名字链接器找不到定义,槽位留着垃圾值,中断一来 PC 跳进垃圾地址。
上拉电阻加电容的经典组合值得单独拆解。上电瞬间电容两端电压不能突变,NRST 被电容短暂拉低,随后经上拉电阻缓缓充电爬升——这段"爬坡时间"保证电源先稳、内核后醒。省掉电容行不行?电源上升极快时可能凑合,但电源有轻微缓升(开关电源软启动、USB 线压降)时,内核可能在电源未稳时就抢跑,症状是十次上电一两次不启动——这种概率性故障在现场极难复现排查,而一颗几分钱的电容就能根除。顺带一答常见疑问:NRST 引脚内部已有弱上拉,外部 10 kΩ 是给它加"确定性",电容才是真正的主角。
STM32F103 的 IO 是 3.3 V 体系,但外设世界仍有大量 5 V 器件(老式传感器、HC 系列逻辑芯片、部分串口模块)。对接规则分两个方向。3.3 V 输出 → 5 V 输入:多数 5 V 器件把 2 V 以上识别为高电平,直连即通。5 V 输出 → 3.3 V 输入:多数 STM32 引脚标注为 FT(five-volt tolerant,5V 容忍),直连安全;非 FT 引脚(如 PA 口的模拟引脚)绝不能接 5 V,会击穿内部保护二极管。判别方法就是查数据手册的引脚定义表,FT 标记一目了然。没有 FT 标记又必须对接时,用电阻分压(上 10 kΩ 下 20 kΩ 把 5 V 折成 3.3 V)或一只 MOS 管做电平转换。
面包板搭建还有一条纪律值得单列:去耦电容要贴着芯片电源脚插。面包板的分布电感本就偏大,去耦电容隔远了等于没接,症状是"接上电机或继电器就随机复位"。跑功率器件时再并一只 10 uF 电解电容压舱,稳定性立刻不同。
软件工程师也应会用两件仪器。万用表用于静态确认:电源脚有没有 3.3 V、地通不通、LED 两端压差是否约 2 V(正常导通)、限流电阻实际阻值(挡位打错读数翻倍是新手常事)。示波器用于动态观察:看复位脚上电时的缓升曲线、看 GPIO 翻转的实际边沿(3.1 节那个"延时 500000"到底是不是 100 ms,一测便知)、看晶振有没有起振(HSE 脚上应有 8 MHz 正弦痕迹)。
没有示波器时的土办法也值得一提:把翻转频率压到肉眼可见(约 1 Hz),用 LED 和耳朵(接蜂鸣器)当低配探头;用串口打印关键变量(第 5 章的 UART 就是为此优先学的)。仪器够不着的地方,降低频率让问题"慢下来"永远是第一招。
本节的电路知识到此够用。下一章回到时间维度:定时器如何把"延时"从 CPU 空转变成了硬件计数,PWM 如何让硬件自动翻电平——呼吸灯就是那时的期末作业。