第 5 章 MCU 最小系统:一块板子的"骨架"
核心问题:一块板子的骨架怎么搭?
5.1 MCU 是什么#
5.1.1 一句话定义#
MCU(Microcontroller Unit,微控制器)= 一个集成在单个芯片里的”微型计算机”。
如果把电脑拆解开,你会发现它有:CPU(大脑)、内存(工作台)、硬盘(仓库)、USB/网口(对外交流)。MCU 把这一切全部塞进了一颗指甲盖大小的芯片里。
5.1.2 一个生活类比#
把 MCU 想象成一个 全能管家:
| 管家能力 | MCU 对应 | 说明 |
|---|---|---|
| 大脑 | CPU 内核 | 执行指令、做运算、做判断 |
| 记忆 | Flash(程序存储器) | 存放你的代码,断电不丢 |
| 工作台 | SRAM(内存) | 程序运行时的临时变量,断电丢失 |
| 手脚 | GPIO(通用输入输出) | 控制 LED、读按键、驱动电机 |
| 感官 | 外设(ADC、UART、SPI、I²C…) | 感知模拟信号、与其他设备通信 |
| 心跳 | 时钟系统(晶振) | 给 CPU 提供节拍,没心跳就”死了” |
5.1.3 GPIO:最基础的手脚#
GPIO(General Purpose Input/Output)是 MCU 最直接的对外接口。每一根引脚都可以被软件配置为:
- 输入:读取外部电平(按键、传感器)
- 输出:输出高/低电平(驱动 LED、控制继电器)
- 特殊功能:被 UART、SPI、I²C 等外设接管
5.1.4 时钟树:MCU 的”心脏和血管”#
MCU 内部有很多模块,它们需要不同频率的时钟信号。时钟树就是描述”时钟从哪里来,怎么分频,送到哪里去”的层级结构。
外部晶振 8MHz ──→ PLL 锁相环 ──→ 72MHz 系统时钟(SYSCLK)
│
┌─────────┼──────────┐
↓ ↓ ↓
AHB 总线 APB1 总线 APB2 总线
(72MHz) (36MHz) (72MHz)
│ │ │
DMA、Flash UART、I²C ADC、SPI1
定时器plaintext💡 关键理解:没有时钟,MCU 就是”死”的。每个外设在使用前,必须先开启它的时钟(在 RCC 寄存器中配置)。这是新手最常忘记的事情!
5.2 GPIO 的工作模式#
STM32 的 GPIO 有 8 种工作模式(F1 系列),是新手最容易搞混的知识点。我们用最通俗的方式讲清楚。
5.2.1 输出模式:推挽 vs 开漏#
推挽输出(Push-Pull)——“能推能拉”#
内部结构:
VDD (3.3V)
│
┌────┴────┐
│ P-MOS │ ← 上管
└────┬────┘
│
├────→ 引脚输出
│
┌────┴────┐
│ N-MOS │ ← 下管
└────┬────┘
│
GNDplaintext工作方式:
- 输出高电平:P-MOS 导通,N-MOS 截止 → 引脚直连 VDD(3.3V)
- 输出低电平:P-MOS 截止,N-MOS 导通 → 引脚直连 GND(0V)
类比:推挽就像两个人接力推门。一个人往前推(输出高),另一个人往后拉(输出低),都能主动发力。
特点:
- 既能输出高电平,也能输出低电平
- 驱动能力强(能灌入/拉出电流)
- 速度快
适用场景:驱动 LED、SPI 通信、普通数字输出
开漏输出(Open-Drain)——“只能拉不能推”#
内部结构:
VDD (外部)
│
[上拉电阻 R] ← 外部必须接!
│
├────→ 引脚输出
│
┌────┴────┐
│ N-MOS │ ← 只有下管
└────┬────┘
│
GNDplaintext工作方式:
- 输出低电平:N-MOS 导通 → 引脚拉到 GND(0V)✓
- 输出高电平:N-MOS 截止 → 引脚悬空(高阻态)⚠️
- 此时电平由外部上拉电阻决定!
- 如果外部上拉到 5V → 引脚输出 5V
- 如果外部没上拉 → 引脚电平不确定(大忌!)
类比:开漏就像只有一个人拉门。他能往下拉(输出低),但想开门(输出高),得靠外面的弹簧(上拉电阻)。
特点:
- 只能主动输出低电平
- 高电平由外部上拉决定 → 可以做电平转换(MCU 是 3.3V,上拉到 5V 就能输出 5V 信号)
- 多个开漏输出可以并联 → 实现线与(任何一个拉低,总线就是低)
适用场景:I²C 通信、电平转换、多设备共享一根线
推挽 vs 开漏 对比速查#
| 特性 | 推挽 | 开漏 |
|---|---|---|
| 输出高 | 主动输出 VDD | 靠外部上拉 |
| 输出低 | 主动拉低到 GND | 主动拉低到 GND |
| 电平转换 | ✗ 不行 | ✓ 上拉到不同电压即可 |
| 线与 | ✗ 会短路烧毁 | ✓ 天然支持 |
| 速度 | 快 | 慢(上拉电阻充电需要时间) |
| 典型用途 | LED、SPI、通用输出 | I²C、中断线、电平转换 |
⚠️ 致命错误:两个推挽输出直接连在一起,一个输出高一个输出低 → VDD 和 GND 直接短路 → 烧芯片!开漏则不会,因为高电平是”放手”而不是”推”。
5.2.2 输入模式:浮空 / 上拉 / 下拉 / 模拟#
① 浮空输入(Floating Input)#
外部信号 ──→ 引脚 ──→ [施密特触发器] ──→ 数据寄存器plaintext- 引脚不接任何内部电阻
- 电平完全由外部决定
- 危险:如果外部什么都没接,引脚电平会在 0 和 1 之间随机跳变,导致功耗暴增、误触发中断
⚠️ 大忌:永远不要让输入引脚悬空(浮空且无外部信号)!
② 上拉输入(Pull-Up Input)#
VDD
│
[内部上拉电阻 ~40kΩ]
│
外部信号 ──┤──→ 引脚 ──→ [施密特触发器] ──→ 数据寄存器plaintext- 内部有一个电阻连到 VDD
- 外部无信号时,引脚默认为 高电平
- 外部拉低时,引脚变为 低电平
适用场景:按键检测(按键一端接引脚,一端接 GND。不按时高电平,按下时低电平)
③ 下拉输入(Pull-Down Input)#
外部信号 ──┤──→ 引脚 ──→ [施密特触发器] ──→ 数据寄存器
│
[内部下拉电阻 ~40kΩ]
│
GNDplaintext- 内部有一个电阻连到 GND
- 外部无信号时,引脚默认为 低电平
- 外部拉高时,引脚变为 高电平
适用场景:按键检测(按键一端接引脚,一端接 VDD)
④ 模拟输入(Analog Input)#
外部模拟信号 ──→ 引脚 ──→ [ADC 模块]
↑
断开数字施密特触发器
(避免数字电路消耗电流)plaintext- 引脚直接连接到内部 ADC
- 数字输入通道被断开,节省功耗,避免数字阈值判断产生额外电流
- 读取的不是 0/1,而是 0~4095(12 位 ADC)这样的数字量
适用场景:接传感器模拟输出(温度、光照、电池电压)
5.2.3 复用功能(Alternate Function)#
MCU 的引脚数量有限,但外设很多。所以很多引脚有”双重身份”:
PA9 ──→ 可以是普通 GPIO
──→ 也可以是 UART1_TX(串口发送)
──→ 也可以是 TIM1_CH2(定时器 PWM 输出)plaintext怎么切换? 在软件中配置 GPIO 为”复用推挽”或”复用开漏”模式,然后在 RCC 中开启对应外设的时钟,外设就接管了这根引脚。
| 复用模式 | 说明 | 典型用途 |
|---|---|---|
| 复用推挽(AF_PP) | 外设输出,推挽驱动 | UART_TX、SPI_MOSI、SPI_SCK |
| 复用开漏(AF_OD) | 外设输出,开漏驱动 | I²C_SCL、I²C_SDA |
💡 一句话总结:
- 输入模式:读外部电平
- 输出模式:写外部电平
- 复用模式:把引脚”借”给外设用
5.3 最小系统的四大件#
最小系统 = 让 MCU 能正常运行的最少外围电路。
就像人活着需要:吃饭(电源)、心跳(时钟)、清醒(复位)、能说话(调试接口)。
5.3.1 第一大件:电源 + 去耦#
呼应第 4 章,这里强调 MCU 特有的几个电源引脚:
| 引脚名 | 作用 | 典型电压 |
|---|---|---|
| VDD | 数字电源(给 CPU、GPIO、数字外设供电) | 3.3V |
| VSS | 数字地 | 0V |
| VDDA | 模拟电源(给 ADC、DAC 供电,需要更干净) | 3.3V |
| VSSA | 模拟地 | 0V |
| VBAT | 备用电源(给 RTC、后备寄存器供电) | 1.8~3.6V(通常接纽扣电池或 VDD) |
| VREF+ | ADC 参考电压(有些型号独立引出) | 通常等于 VDDA |
去耦电容配置规则:
每一对 VDD-VSS 引脚:就近放一个 100nF(0402 或 0603)
VDDA 引脚:100nF + 1μF(更严格的滤波)
VBAT:100nF(如果接电池)
总电源入口:10μF(储能)plaintext实际原理图连接(以 STM32F103 为例):
3.3V ──┬──→ VDD (引脚 1) ──→ VDDA (引脚 21)
│ │ │
[10μF] [100nF] [1μF] [100nF]
│ │ │ │
GND ──┴──→ VSS (引脚 8) ──→ VSSA (引脚 20)plaintext⚠️ 常见错误:
- VDDA 没接或没加电容 → ADC 读数乱跳
- VBAT 悬空 → 内部 RTC 不工作(即使不用 RTC,也建议接 VDD 或 GND,看 datasheet)
5.3.2 第二大件:复位电路#
为什么需要复位?
MCU 上电瞬间,电源电压从 0 爬升到 3.3V 需要时间。在这个过程中,电压不稳定,CPU 可能执行错误指令,寄存器状态不可预知。复位电路的作用就是:在电源稳定之前,把 MCU 按在”重启”状态,等电源稳定了再松手。
方案一:RC 复位电路(最常用)#
STM32 的 NRST 引脚是低电平有效(拉低 = 复位)。
3.3V
│
[10kΩ] ← 上拉电阻
│
├────→ NRST
│
[100nF] ← 充电电容
│
[按键] │
│ │
GND GNDplaintext工作过程:
- 上电瞬间:电容两端电压不能突变 → NRST 被拉低到 0V → MCU 处于复位状态
- 电容充电:3.3V 通过 10kΩ 电阻给电容充电 → NRST 电压逐渐升高
- 充电完成:NRST ≈ 3.3V → MCU 退出复位,开始运行
充电时间常数:τ = R × C = 10kΩ × 100nF = 1ms
实际稳定到 3.3V 约需 35τ = 35ms,足够让电源稳定。
手动复位:按下按键 → 电容放电 → NRST 被拉到 GND → MCU 复位。松开按键 → 电容重新充电 → MCU 恢复运行。
⚠️ 注意:STM32 内部已有弱上拉电阻(约 40kΩ),但外部加 10kΩ 更可靠。
方案二:专用复位芯片#
在对可靠性要求高的场景(工业、汽车),推荐使用专用复位芯片:
3.3V ──→ [复位芯片] ──→ NRST
(如 STM813、
IMP811、
MAX809)plaintext优点:
- 精确的复位阈值(如 2.93V,比 RC 电路精确得多)
- 保证足够长的复位脉冲(如 200ms)
- 带看门狗功能(部分型号)
- 电源跌落时也能触发复位
| 芯片 | 复位阈值 | 特点 |
|---|---|---|
| MAX809 | 多种可选(3.08V、2.93V 等) | 经典款 |
| STM813 | 2.93V + 看门狗 | 带 WDT |
| IMP811 | 多种可选 | 国产替代 MAX811 |
5.3.3 第三大件:晶振电路#
为什么 MCU 需要晶振?
MCU 的 CPU 是同步电路——每一步操作都需要一个时钟脉冲来”指挥”。没有时钟信号,CPU 就像没有指挥的乐队,完全瘫痪。
晶振(Crystal Oscillator)就是提供这个精确时钟信号的元件。
两种晶振#
| 类型 | 典型频率 | 用途 |
|---|---|---|
| 高速外部晶振(HSE) | 8MHz(最常用) | 系统主时钟,经 PLL 倍频到 72MHz |
| 低速外部晶振(LSE) | 32.768kHz | RTC 实时时钟(精确计秒) |
💡 STM32 内部也有振荡器(HSI 8MHz、LSI 40kHz),但精度较差(±1%~±40%),适合简单场景。需要精确时钟(USB、以太网)时必须用外部晶振。
无源晶振电路#
┌──── [C1 = 20pF] ──── GND
│
OSC_IN ───┤
│
[晶振 8MHz]
│
OSC_OUT ──┤
│
└──── [C2 = 20pF] ──── GNDplaintext负载电容怎么算?
晶振 datasheet 会给出一个 负载电容
其中
举例:晶振
💡 懒人做法:大多数 8MHz 晶振配 20pF 或 22pF 电容就能正常工作。如果对频率精度要求极高(如 USB),再精细计算。
有源晶振 vs 无源晶振#
| 无源晶振 | 有源晶振 | |
|---|---|---|
| 引脚数 | 2 | 4(VDD、GND、OUT、EN) |
| 需要外部电容 | ✓ 需要 | ✗ 不需要 |
| 精度 | 一般(±20ppm) | 高(±10ppm 甚至更好) |
| 成本 | 便宜(几毛) | 较贵(几块~几十块) |
| 尺寸 | 小 | 较大 |
| 典型用途 | MCU 主时钟 | 射频、以太网、高精度场景 |
晶振 PCB 布局铁律#
| 规则 | 原因 |
|---|---|
| 晶振尽量靠近 MCU 的 OSC 引脚 | 走线越长,寄生参数越大,越容易受干扰 |
| 晶振下方不走任何其他信号线 | 晶振的高频信号会耦合到下方走线 |
| 晶振周围包地(铺铜隔离) | 减少对外辐射 |
| 晶振走线不做 90° 直角 | 减少反射 |
| 负载电容紧贴晶振引脚 | 减小环路面积 |
5.3.4 第四大件:下载/调试接口#
MCU 需要一种方式把程序”灌”进去,并且在出问题时”看”里面在干什么。这就是调试接口。
SWD vs JTAG#
| 特性 | SWD(Serial Wire Debug) | JTAG |
|---|---|---|
| 信号线数 | 2 根(SWDIO + SWCLK) | 5 根(TMS、TCK、TDI、TDO、nTRST) |
| 加电源地 | 共 4 根(+VCC +GND) | 共 7 根 |
| 功能 | 全功能调试 + 下载 | 全功能调试 + 下载 + 边界扫描 |
| 占用 GPIO | 少(PA13、PA14) | 多(PA13~PA15、PB3、PB4) |
| 速度 | 快(可达 10Mbps+) | 快 |
| 适用场景 | 绝大多数 Cortex-M 项目 | 复杂 SoC、多核调试 |
💡 结论:除非你有特殊需求,永远选 SWD。它省引脚、省面积、一样好用。
SWD 接口接线#
调试器(ST-Link / J-Link) MCU(STM32)
┌──────────────────┐ ┌──────────────┐
│ 1. VCC (3.3V) │ ───────→ │ VDD │
│ 2. SWDIO │ ←──────→ │ PA13 │
│ 3. SWCLK │ ───────→ │ PA14 │
│ 4. GND │ ───────→ │ GND │
│ (5. NRST 可选) │ ───────→ │ NRST │
└──────────────────┘ └──────────────┘plaintext关键细节:
- VCC(VTref):调试器通过这根线检测目标板的电压(3.3V 还是 1.8V),以匹配信号电平。必须接! 很多新手忘了接这根线,导致调试器报 “Cannot connect to target”。
- NRST:可选。接了可以在连接失败时通过硬件复位”救活”芯片。
- SWDIO 和 SWCLK:STM32 内部已有上拉/下拉电阻,外部不需要再加。
常见调试器#
| 调试器 | 价格 | 特点 |
|---|---|---|
| ST-Link V2(国产克隆版) | ~10 元 | 便宜、够用、STM32 专用 |
| ST-Link V3 | ~80 元 | 官方正品,速度快 |
| J-Link V11(正版) | ~2000 元 | 功能最全,支持所有 ARM |
| DAPLink / CMSIS-DAP | ~30 元 | 开源方案,免驱 |
5.4 看门狗(Watchdog)#
5.4.1 为什么需要看门狗?#
场景:你的设备在野外运行,7×24 小时不间断。突然一次电磁干扰(打雷、电机启动),程序”跑飞”了——CPU 跳到了一个错误的地址,开始执行乱七八糟的指令,或者直接卡死在死循环里。
这时候,没有人能帮你按复位键。设备就永远”死”了。
看门狗的作用:它是一个独立的硬件定时器。你必须定期”喂狗”(重置定时器)。如果程序正常运行,你会按时喂狗,看门狗不会动作。如果程序跑飞了,没人喂狗,定时器超时 → 自动触发硬件复位 → MCU 重启 → 恢复正常。
正常流程:
程序运行 → 喂狗 → 定时器重置 → 继续运行 → 喂狗 → ...
异常流程:
程序跑飞 → 没人喂狗 → 定时器超时 → 硬件复位 → 程序重新开始plaintext5.4.2 STM32 的两种看门狗#
独立看门狗(IWDG)——“宠物狗”#
- 时钟源:独立的内部低速 RC 振荡器(LSI,约 32~40kHz)
- 特点:即使主时钟(HSE/PLL)坏了,IWDG 照样工作
- 配置后不可停止(只能通过复位关闭)
- 精度差:LSI 频率误差可达 ±30%,所以超时时间不精确
- 适用场景:防止程序死机(最常用)
工作流程:
- 设置预分频系数和重装载值
- 启动 IWDG
- 在主循环中定期调用”喂狗”指令
- 如果超时没喂 → 产生系统复位
超时时间计算:
| 预分频系数 | 分频值 | 最大超时(reload=0xFFF) |
|---|---|---|
| 0 | /4 | ~0.5s |
| 3 | /32 | ~4s |
| 6 | /256 | ~32s |
实际配置举例:
假设需要 1 秒超时:
- LSI = 40kHz
- 预分频 = /64 → 40000/64 = 625Hz
- 重装载值 = 625 - 1 = 624
- 超时时间 = 625 / 625 = 1.0s ✓
// HAL 库配置示例
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_64; // /64
hiwdg.Init.Reload = 624; // 重装载值
HAL_IWDG_Init(&hiwdg);
// 在主循环中喂狗
while (1) {
// ... 你的业务逻辑 ...
HAL_IWDG_Refresh(&hiwdg); // 喂狗!
}c⚠️ 调试大坑:调试器暂停程序(打断点)时,IWDG 还在跑!会导致你在调试时被看门狗复位。解决方案:在调试器设置中勾选”调试时冻结 IWDG”(Freeze IWDG in debug)。
窗口看门狗(WWDG)——“警犬”#
- 时钟源:系统时钟(APB1)分频
- 特点:必须在指定的时间窗口内喂狗
- 喂早了 → 复位!(防止程序跑飞后仍然在疯狂喂狗)
- 喂晚了 → 复位!(程序卡死了)
- 精度好:基于系统时钟
- 适用场景:安全关键系统(工业控制、医疗设备),确保程序严格按照时序执行
时间线:
├─────┼──────────┼──────┼──→
0 窗口开始 窗口结束 超时
(最早喂狗) (最晚喂狗)
喂早了 → 复位 ✗
窗口内喂 → 正常 ✓
喂晚了 → 复位 ✗plaintext5.4.3 外部看门狗芯片#
在一些高可靠性场景(汽车、航天),不信任 MCU 内部的看门狗(万一 MCU 内部逻辑坏了,看门狗也坏了呢?)。这时用外部看门狗芯片:
| 芯片 | 特点 |
|---|---|
| MAX823 / MAX824 | 带看门狗 + 复位 + 电源监控 |
| TPS3823 | TI 出品,低功耗 |
| CAT823 | 国产替代 |
工作原理:MCU 必须定期翻转一个 GPIO → 外部芯片检测翻转 → 如果超时没翻转 → 外部芯片拉低 NRST → 硬件复位。
5.5 存储器接口#
MCU 内部的 Flash 容量有限(STM32F103 通常 64KB~512KB)。当你需要存储更多数据(日志、配置、图片、字库),就需要外部存储器。
5.5.1 SPI Flash(W25Q64 / W25Q128)#
最常用的外部大容量存储方案。
| 型号 | 容量 | 接口 | 速度 | 擦写次数 | 典型用途 |
|---|---|---|---|---|---|
| W25Q64 | 64Mbit (8MB) | SPI | 80MHz | 10万次 | 日志、字库、OTA 固件 |
| W25Q128 | 128Mbit (16MB) | SPI | 80MHz | 10万次 | 大日志、图片 |
| W25Q256 | 256Mbit (32MB) | QSPI | 104MHz | 10万次 | 大型文件系统 |
与 MCU 的连接(SPI 四线制):
STM32 W25Q64
┌──────────┐ ┌──────────┐
│ PA5 │ ────────→ │ CLK │
│ (SCK) │ │ │
│ │ │ │
│ PA7 │ ────────→ │ DI (MOSI)│
│ (MOSI) │ │ │
│ │ │ │
│ PA6 │ ←──────── │ DO (MISO)│
│ (MISO) │ │ │
│ │ │ │
│ PA4 │ ────────→ │ CS │
│ (GPIO) │ │ │
│ │ │ │
│ 3.3V │ ────────→ │ VCC │
│ GND │ ────────→ │ GND │
└──────────┘ └──────────┘plaintext关键设计要点:
- CS 引脚需要上拉电阻(10kΩ 到 VCC),防止 MCU 启动时 CS 悬空导致 Flash 误动作
- SPI 走线尽量短且等长(高速时)
- VCC 加 100nF 去耦电容
- WP(写保护)引脚:如果不使用硬件写保护,接高电平(VCC)
- HOLD 引脚:如果不使用暂停功能,接高电平(VCC)
5.5.2 EEPROM(AT24C02 / M24C64)#
适合存储少量但需要频繁修改的配置数据。
| 型号 | 容量 | 接口 | 擦写次数 | 典型用途 |
|---|---|---|---|---|
| AT24C02 | 2Kbit (256 字节) | I²C | 100万次 | 存校准参数、用户设置 |
| AT24C64 | 64Kbit (8KB) | I²C | 100万次 | 存更多配置 |
| M24C64 | 64Kbit (8KB) | I²C | 100万次 | ST 出品,同上 |
与 MCU 的连接(I²C 两线制):
STM32 AT24C02
┌──────────┐ ┌──────────┐
│ PB6 │ ←──┬──→ │ SCL │
│ (SCL) │ │ │ │
│ │ │ │ │
│ PB7 │ ←──┼──→ │ SDA │
│ (SDA) │ │ │ │
│ │ [4.7kΩ]│ │
│ │ [4.7kΩ]│ │
│ │ │ │ │
│ 3.3V │ │ ┌→ │ VCC │
│ GND │ ───┴──→ │ GND │
└──────────┘ └──────────┘plaintextI²C 地址:AT24C02 有 A0、A1、A2 三个地址引脚,决定 I²C 设备地址。全部接 GND 时地址为 0x50。
EEPROM vs SPI Flash 对比:
| 特性 | EEPROM | SPI Flash |
|---|---|---|
| 容量 | 小(256B ~ 64KB) | 大(1MB ~ 32MB) |
| 擦写粒度 | 字节级(改 1 个字节不用擦整页) | 页级(写之前必须擦除整扇区) |
| 擦写次数 | 100 万次 | 10 万次 |
| 速度 | 慢(I²C 400kHz) | 快(SPI 80MHz) |
| 适合存什么 | 频繁修改的小数据(配置、校准) | 大量数据(日志、固件) |
5.5.3 SD 卡(SPI / SDIO)#
当需要 GB 级存储(数据记录、音频文件)时,SD 卡是最佳选择。
连接方式有两种:
| 模式 | 速度 | 接线数 | 适用场景 |
|---|---|---|---|
| SPI 模式 | 慢(~10MB/s) | 4 线 | 低速数据记录 |
| SDIO 模式 | 快(~50MB/s) | 6 线 | 需要高速读写 |
SPI 模式接线:
STM32 SD 卡座
┌──────────┐ ┌──────────┐
│ SCK │ ────────→ │ CLK │
│ MOSI │ ────────→ │ CMD │
│ MISO │ ←──────── │ DAT0 │
│ GPIO │ ────────→ │ CS (DAT3)│
│ 3.3V │ ────────→ │ VDD │
│ GND │ ────────→ │ GND │
└──────────┘ └──────────┘plaintext注意事项:
- SD 卡工作在 3.3V,绝对不能接 5V
- CS、CLK、CMD、DAT 线都需要 10kΩ~47kΩ 上拉电阻
- 需要配合 FatFS 文件系统 才能像 U 盘一样读写文件
5.6 未使用引脚的处理#
这是一条铁律:未使用的 GPIO 引脚不能悬空!
5.6.1 为什么不能悬空?#
悬空的引脚就像一根天线:
- 电磁干扰:拾取周围的高频噪声
- 电平不定:内部 CMOS 输入级在阈值附近反复跳变 → 静态功耗暴增(可能从 μA 级涨到 mA 级)
- 闩锁风险:极端情况下,噪声可能触发内部寄生晶闸管 → 芯片烧毁
5.6.2 正确的处理方式#
| 方法 | 做法 | 推荐度 |
|---|---|---|
| 配置为模拟输入 | 软件中设为 Analog Input | ⭐⭐⭐ 最推荐(功耗最低) |
| 外部下拉 | 接 10kΩ 电阻到 GND | ⭐⭐ 可靠但费板面积 |
| 内部上拉/下拉 | 软件中开启内部上拉或下拉 | ⭐⭐ 简单 |
| 输出低 | 配置为推挽输出并输出低 | ⭐ 可用但不优雅 |
💡 经验法则:
- 在软件初始化时,把所有未使用的引脚配置为模拟输入(Analog Input)
- 这是 ST 官方推荐的做法,功耗最低
- 对于 BOOT 引脚等硬件相关的引脚,必须用外部电阻固定电平
5.7 BOOT 引脚配置#
5.7.1 三种启动模式#
STM32 上电时,根据 BOOT 引脚的状态决定从哪个存储器启动:
| BOOT0 | BOOT1 (PB2) | 启动位置 | 地址 | 用途 |
|---|---|---|---|---|
| 0 | X(任意) | 主 Flash | 0x0800 0000 | 正常运行(99% 的情况) |
| 1 | 0 | 系统存储器 | 0x1FFF 0000 | 出厂 Bootloader(串口 ISP 下载) |
| 1 | 1 | SRAM | 0x2000 0000 | 调试用(掉电丢失) |
5.7.2 硬件配置#
最常用的配置:BOOT0 = 0(从 Flash 启动)
BOOT0 ──── [10kΩ] ──── GND ← 下拉到 GND,确保启动从 Flash
BOOT1 ──── [10kΩ] ──── GND ← 下拉到 GND(或者作为普通 GPIO PB2 使用)plaintext如果需要串口下载(ISP)功能:
BOOT0 ──── [10kΩ] ──── GND
│
[拨码开关/跳线帽]
│
3.3Vplaintext- 正常使用:跳线帽断开 → BOOT0 = 0 → 从 Flash 启动
- 需要串口下载时:跳线帽接上 → BOOT0 = 1 → 进入 Bootloader → 用串口下载程序
⚠️ 绝对不能让 BOOT 引脚悬空! 悬空时电平不确定,可能每次都进入 Bootloader 模式,你的程序”看起来没运行”。
5.8 实际案例分析:拆解一块 STM32 开发板的原理图#
让我们以经典的 STM32F103C8T6 最小系统板(俗称”蓝色小板”,淘宝几块钱一块)为例,逐模块拆解它的原理图。
5.8.1 整体架构#
┌──────────────────────────────────────────────────────────┐
│ STM32F103C8T6 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ │
│ │ 电源 │ │ 复位 │ │ 晶振 │ │ SWD 接口 │ │
│ │ 3.3V │ │ RC 电路 │ │ 8MHz │ │ 4P 排针 │ │
│ │ + 去耦 │ │ + 按键 │ │ + 22pF │ │ │ │
│ └─────────┘ └─────────┘ └─────────┘ └───────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ BOOT0 │ │ LED │ │ USB │ │
│ │ 跳线 │ │ PC13 │ │ 供电 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ 引出所有 GPIO 的排针 │
└──────────────────────────────────────────────────────────┘plaintext5.8.2 逐模块分析#
① 电源部分#
USB 5V ──→ [AMS1117-3.3] ──→ 3.3V ──→ 所有 VDD 引脚
│ │
[10μF] [100nF] × 5
│ │
GND GNDplaintext- AMS1117-3.3 把 USB 5V 降到 3.3V
- 输入端 10μF + 输出端 10μF(LDO 标配)
- 每个 VDD 引脚就近一个 100nF
② 复位电路#
3.3V ──→ [10kΩ] ──┬──→ NRST
│
[100nF]
│
[复位按键]
│
GNDplaintext经典 RC 复位,上电自动复位 + 手动按键复位。
③ 晶振电路#
OSC_IN ──┬── [22pF] ── GND
│
[8MHz 晶振]
│
OSC_OUT ─┬── [22pF] ── GNDplaintext8MHz 无源晶振 + 22pF 负载电容。内部 PLL 倍频到 72MHz。
💡 这块板上通常不焊 32.768kHz 低速晶振(省成本),RTC 只能用内部 LSI(精度差)。
④ SWD 调试接口#
4P 排针:
1. GND
2. SWCLK (PA14)
3. SWDIO (PA13)
4. 3.3Vplaintext配合 ST-Link 使用,4 根线完成下载和调试。
⑤ BOOT 配置#
BOOT0 ── [10kΩ] ── GND(默认从 Flash 启动)
跳线帽可选接 3.3V(进入串口下载模式)
BOOT1 ── [10kΩ] ── GND(PB2 作为普通 GPIO 时不影响)plaintext⑥ 板载 LED#
3.3V ──→ [510Ω] ──→ [LED] ──→ PC13plaintextPC13 是 STM32 上著名的”板载 LED 引脚”。输出低电平时 LED 亮(灌电流方式)。
⚠️ PC13 的坑:它的驱动能力很弱(最大 3mA),不能用来直接驱动大功率 LED 或继电器。
5.8.3 这块板子的优缺点#
| 优点 | 缺点 |
|---|---|
| 便宜(5~10 元) | AMS1117 效率低,大压差发热 |
| 够用(学习和小项目足够) | 没有 32.768kHz 晶振 |
| 面包板友好 | 没有板载 USB 转串口 |
| 社区资料极多 | 晶振质量参差不齐 |
本章小结#
| 知识点 | 一句话记住 |
|---|---|
| MCU | 集成在单芯片里的微型计算机 |
| GPIO 推挽 | 能推能拉,通用输出 |
| GPIO 开漏 | 只能拉不能推,I²C 专用 |
| 电源去耦 | 每个 VDD 引脚 100nF,VDDA 要更干净 |
| 复位电路 | RC 低电平复位,保证上电时 NRST 先低后高 |
| 晶振 | 8MHz + 20pF 负载电容,靠近 MCU,下方不走线 |
| SWD 调试 | 4 根线(VCC/GND/SWDIO/SWCLK)搞定一切 |
| 看门狗 | 程序跑飞的最后一道防线,记得喂狗 |
| 存储器 | SPI Flash 存大数据,EEPROM 存小配置 |
| 未使用引脚 | 绝对不能悬空!配置为模拟输入 |
| BOOT 引脚 | 下拉到 GND(从 Flash 启动),不能悬空 |
实战 Checklist:MCU 最小系统自检清单#
- 所有 VDD 引脚都接了 3.3V
- 所有 VSS 引脚都接了 GND
- 每对 VDD-VSS 就近有 100nF 去耦电容
- VDDA 有独立的 1μF + 100nF 滤波
- VBAT 已接(VDD 或电池或 GND,看 datasheet)
- NRST 有 RC 复位电路(10kΩ + 100nF)
- 有手动复位按键
- 8MHz 晶振 + 负载电容已焊接
- 晶振靠近 MCU,下方无其他走线
- SWD 接口引出(至少 SWDIO、SWCLK、GND、VCC)
- BOOT0 有下拉电阻(10kΩ 到 GND)
- BOOT1 有确定电平(下拉或作为 GPIO 使用)
- 未使用的引脚在软件中配置为模拟输入
- 开启了 IWDG 看门狗
推荐进一步阅读#
- ST 应用笔记:《AN2867 - STM32F10xxx 硬件开发入门》
- ST 参考手册:《RM0008 - STM32F101xx/102xx/103xx/105xx/107xx Reference Manual》
- ST 数据手册:对应型号的 Datasheet(查引脚定义和绝对最大额定值)
- 《ARM Cortex-M3 权威指南》(Joseph Yiu 著)
下一章预告:第 6 章 输入电路——MCU 的骨架搭好了,接下来看信号怎么进来:按键、ADC、传感器,各种信号调理电路一网打尽。