Appearance
微控制器原理与选型
微控制器(MCU,Microcontroller Unit)是嵌入式系统的核心。它把 CPU、内存、Flash、外设控制器集成在一颗芯片上,能独立运行程序控制外部硬件。理解 MCU 的内部结构是写好固件的前提。
一、MCU vs MPU vs SoC
| 类型 | 全称 | 特点 | 典型代表 |
|---|---|---|---|
| MCU | Microcontroller Unit | CPU+Flash+RAM+外设一体,跑裸机或 RTOS,无 MMU | STM32F1/F4、ESP32-C3 |
| MPU | Microprocessor Unit | 只有 CPU 核心,需要外挂 RAM/Flash,有 MMU,跑 Linux | i.MX6ULL、全志 T113 |
| SoC | System on Chip | 集成 CPU+GPU+DSP+NPU+外设,手机/路由器级别 | 高通骁龙、瑞芯微 RK3588 |
嵌入式入门从 MCU 开始。MCU 的优势是启动快(微秒级)、功耗低(µA 级休眠)、确定性强(无 OS 调度抖动)。
二、CPU 架构
ARM Cortex-M 系列
嵌入式 MCU 市场的绝对主力。ARM 不造芯片,只卖 IP 授权,各厂商(ST、NXP、TI、GD)买了 IP 加自己的外设做成芯片。
| 内核 | 特点 | 典型芯片 |
|---|---|---|
| Cortex-M0/M0+ | 最小最省电,适合低成本低功耗 | STM32L0、nRF52810 |
| Cortex-M3 | 平衡性能和功耗,Thumb-2 指令集 | STM32F103、GD32F103 |
| Cortex-M4 | 加 FPU 和 DSP 指令,适合信号处理 | STM32F407、nRF52840 |
| Cortex-M7 | 高性能,6 级流水线,双发射,带 Cache | STM32H743、i.MXRT1060 |
| Cortex-M33 | ARMv8-M,TrustZone 安全扩展 | STM32L5、LPC55S69 |
RISC-V
开源指令集架构,近年在国产 MCU 中快速普及。
- GD32VF103:兆易创新,Cortex-M3 级别性能,国产替代
- BL602/BL616:博流智能,带 Wi-Fi/BLE
- ESP32-C3/C6:乐鑫,RISC-V + Wi-Fi/BLE,生态成熟
RISC-V 的优势:无授权费、可定制扩展指令、工具链开源(GCC/LLVM 原生支持)。
三、存储体系
MCU 内部存储分两块:
Flash(程序存储器)
- 存放编译后的固件代码(.text 段)和常量数据(.rodata 段)
- 掉电不丢失
- 写入需要先擦除(按扇区/页),写入次数有限(通常 10K~100K 次)
- 典型大小:64KB ~ 2MB
SRAM(运行时内存)
- 存放全局变量、栈、堆
- 掉电丢失
- 读写速度快,无擦写限制
- 典型大小:8KB ~ 1MB
内存映射
MCU 把所有外设、Flash、SRAM 统一编址到一个 32 位地址空间:
0x0000_0000 ~ 0x07FF_FFFF Flash(代码区)
0x2000_0000 ~ 0x3FFF_FFFF SRAM(数据区)
0x4000_0000 ~ 0x5FFF_FFFF 外设寄存器
0xE000_0000 ~ 0xFFFF_FFFF 系统外设(NVIC、SysTick、SCB)这就是为什么操作外设就是读写特定地址——寄存器本质上是映射到地址空间的硬件触发器。
四、时钟树
MCU 内部有多个时钟源,通过分频/倍频/选择器组成"时钟树",给不同模块提供不同频率的时钟。
HSE(外部晶振 8MHz)
└─→ PLL(倍频) ─→ SYSCLK(168MHz)
├─→ AHB(168MHz) ─→ DMA、GPIO、Flash
├─→ APB2(84MHz) ─→ USART1、SPI1、TIM1
└─→ APB1(42MHz) ─→ USART2、I2C、TIM2~7
HSI(内部RC 16MHz) ─→ 备用系统时钟
LSE(外部 32.768kHz) ─→ RTC
LSI(内部 32kHz) ─→ 看门狗配置时钟是初始化 MCU 的第一步。时钟配错会导致:串口乱码(波特率算错)、外设不工作(时钟没开)、功耗过高(频率太高)。
STM32 用 CubeMX 的时钟树图形化配置工具可以直观调整。
五、中断系统
中断是 MCU 响应外部事件的核心机制。当事件发生(按键按下、数据接收完成、定时器溢出),CPU 暂停当前代码,跳转到中断服务函数(ISR)执行,完成后返回。
NVIC(嵌套向量中断控制器)
ARM Cortex-M 的中断管理器,特点:
- 向量表:每个中断有固定的入口地址,存在 Flash 起始位置
- 优先级:数字越小优先级越高,支持抢占优先级 + 子优先级
- 嵌套:高优先级中断可以打断低优先级中断
- 尾链:连续中断不需要完整的入栈出栈,减少延迟
中断编程要点
c
// 中断服务函数要短小精悍
void USART1_IRQHandler(void) {
if (USART1->SR & USART_SR_RXNE) {
uint8_t data = USART1->DR; // 读数据,同时清标志
ring_buffer_push(&rx_buf, data);
}
}- ISR 里不要做耗时操作(不要 printf、不要 delay、不要 malloc)
- 用标志位或队列把数据传给主循环处理
- 共享变量要用
volatile修饰 - 注意中断优先级配置,避免优先级反转
六、启动流程
MCU 上电后的执行顺序:
- 硬件复位:所有寄存器恢复默认值
- 取初始 SP 和 PC:从地址 0x0000_0000 读取初始栈指针,从 0x0000_0004 读取复位向量(Reset_Handler 地址)
- Reset_Handler:
- 初始化 .data 段(从 Flash 拷贝初始值到 SRAM)
- 清零 .bss 段
- 调用 SystemInit()(配置时钟)
- 调用 __libc_init_array()(C++ 全局构造函数)
- 跳转到 main()
- main():用户代码开始执行
这个流程由启动文件(startup_stm32f4xx.s)和链接脚本(STM32F407.ld)共同控制。理解它才能做 Bootloader、自定义内存布局、多固件分区。
七、低功耗模式
MCU 的功耗与时钟频率和活跃外设数量成正比。大多数 MCU 提供多级低功耗模式:
| 模式 | STM32 对应 | 功耗 | 唤醒时间 | 保留内容 |
|---|---|---|---|---|
| 正常运行 | Run | 数十 mA | - | 全部 |
| 睡眠 | Sleep | 数 mA | 几 µs | CPU 停,外设继续 |
| 深度睡眠 | Stop | 数十 µA | 几 µs | SRAM 保留,时钟停 |
| 待机 | Standby | 数 µA | 几 ms | 仅备份寄存器和 RTC 保留 |
| 关断 | Shutdown | nA 级 | 几十 ms | 几乎等于断电重启 |
电池供电产品(手环、传感器节点)的核心挑战就是在"干活"和"睡觉"之间快速切换。
八、选型方法
选 MCU 不是选"最强的",而是选"刚好够用且供应稳定的"。
选型维度
| 维度 | 考虑因素 |
|---|---|
| 性能 | 主频、Flash/RAM 大小、是否需要 FPU/DSP |
| 外设 | 需要几路 UART/SPI/I2C/CAN/USB/ADC |
| 功耗 | 电池供电?低功耗模式的电流和唤醒时间 |
| 封装 | QFP 方便手焊调试,QFN/BGA 适合量产小型化 |
| 生态 | 开发工具、文档质量、社区活跃度、参考设计 |
| 供应链 | 是否容易买到、交期、是否有国产替代 |
| 成本 | 单价 × 量,还要算 PCB 面积、外围元件数量 |
常见选型路线
| 场景 | 推荐 |
|---|---|
| 学习入门 | STM32F103C8T6(便宜、资料多) |
| 通用产品原型 | STM32F407(性能够、外设全) |
| 低功耗电池产品 | STM32L4 / nRF52840 |
| Wi-Fi + BLE IoT | ESP32-S3 / ESP32-C3 |
| 高性能实时控制 | STM32H7 / i.MXRT1060 |
| 国产替代 | GD32F103 / CH32V307(RISC-V) |
| 超低成本(< 1 元) | PY32F002 / CH32V003 |
数据手册怎么读
拿到一颗新 MCU,按这个顺序读文档:
- Datasheet:引脚定义、电气参数、封装尺寸 → 确认能不能用
- Reference Manual:寄存器详解、外设工作原理 → 写驱动时查
- Programming Manual:指令集、内核寄存器 → 写汇编或调试时查
- Errata:已知硬件 Bug → 量产前必看,避免踩坑
- Application Note:官方应用笔记 → 特定场景的最佳实践
返回 总览与学习路线
