跳转至

STM32

STM32 是 ST 公司基于 ARM Cortex-M 内核的 32 位微控制器系列,广泛应用于嵌入式开发、机器人控制、物联网等领域。本板块系统梳理 STM32 的核心外设与编程方法。


STM32 是什么?

STM32 = ST(意法半导体公司)+ M(Microcontroller,微控制器)+ 32(32 位架构)

它不是一颗芯片,而是一个庞大的产品系列。以最常用的 STM32F103C8T6 为例:

字段 含义
STM32 ST 公司的 32 位 MCU
F 基础型(Foundation),还有 L(低功耗)、H(高性能)等
103 系列编号,103 表示增强型,基于 Cortex-M3 内核
C 48 引脚
8 64KB Flash
T LQFP 封装
6 工作温度范围 -40°C ~ 85°C

开发板推荐

入门推荐 STM32F103C8T6(蓝色小板 / Blue Pill),便宜好用。进阶推荐 STM32F407 系列,主频更高(168MHz),外设更丰富。


核心架构概览

STM32 的内部结构可以抽象为以下几个层次:

graph TB
    CPU[Cortex-M 内核 CPU] --> BUS[总线矩阵 Bus Matrix]
    BUS --> AHB[AHB 总线]
    BUS --> APB1[APB1 总线 低速]
    BUS --> APB2[APB2 总线 高速]
    AHB --> FLASH[Flash 存储器]
    AHB --> SRAM[SRAM 内存]
    AHB --> DMA[DMA 控制器]
    AHB --> RCC[时钟控制 RCC]
    APB2 --> GPIO_A[GPIOA/B/C...]
    APB2 --> ADC_M[ADC]
    APB2 --> TIM1_M[高级定时器 TIM1]
    APB2 --> USART1_M[USART1]
    APB2 --> SPI1_M[SPI1]
    APB1 --> TIM2_M[通用定时器 TIM2/3/4]
    APB1 --> USART2_M[USART2/3]
    APB1 --> I2C_M[I2C1/2]
    APB1 --> SPI2_M[SPI2]
    APB1 --> DAC_M[DAC]

总线层级关系

  • AHB(Advanced High-performance Bus):挂载高速外设,如 Flash、SRAM、DMA
  • APB2(Advanced Peripheral Bus 2):高速外设总线,挂载 GPIO、ADC、USART1、高级定时器
  • APB1:低速外设总线,挂载 I2C、SPI2、通用定时器、DAC

APB1 最高频率是 AHB 的一半。理解总线层级有助于理解时钟分频配置。


开发方式

STM32 有三种主流开发方式,各有优劣:

直接操作硬件寄存器,每一位都手动控制。

// 点亮 PC13 上的 LED
RCC->APB2ENR |= (1 << 4);       // 使能 GPIOC 时钟
GPIOC->CRH &= ~(0xF << 20);     // 清除 PC13 配置
GPIOC->CRH |= (0x3 << 20);      // 设置为推挽输出,50MHz
GPIOC->ODR &= ~(1 << 13);       // PC13 输出低电平(LED 亮)

优点:效率最高,理解最深
缺点:代码可读性差,开发速度慢

ST 官方提供的 C 语言函数库,对寄存器操作做了一层封装。

// 点亮 PC13 上的 LED
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_ResetBits(GPIOC, GPIO_Pin_13);  // 输出低电平

优点:代码清晰,学习资料丰富
缺点:ST 已停止更新,新芯片不再支持

最新的官方开发方式,通过 CubeMX 图形化工具配置引脚和时钟,自动生成初始化代码。

// CubeMX 自动生成初始化代码后,用户只需:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);  // LED 亮
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);     // LED 灭

优点:开发效率最高,可移植性好,适合快速原型
缺点:封装层次多,运行效率略低,出问题时需要深入理解底层

建议

推荐使用 HAL 库 + CubeMX,这是 ST 官方主推的开发方式,资料丰富、社区活跃,适合快速开发和学习。本笔记所有代码示例均基于 HAL 库。了解寄存器原理有助于排查问题,但日常开发不必手动操作寄存器。


编程的基本流程

使用 HAL 库 + CubeMX 的开发流程如下:

graph LR
    A[1. CubeMX 配置<br>引脚/时钟/外设] --> B[2. 生成工程代码]
    B --> C[3. 在 USER CODE 区域<br>编写业务逻辑]
    C --> D[4. 编译下载调试]
  1. CubeMX 图形化配置:选型号 → 配置引脚功能 → 配置时钟树 → 配置外设参数 → 配置中断和 DMA
  2. 生成代码:CubeMX 自动生成初始化函数(MX_GPIO_Init()MX_TIM2_Init() 等),包含时钟使能、引脚配置、外设配置
  3. 编写用户代码:在 /* USER CODE BEGIN *//* USER CODE END */ 之间写业务逻辑,这样重新生成代码时不会被覆盖
  4. 编译调试:编译下载到开发板,通过串口/调试器观察结果

CubeMX 重要规则

永远只在 USER CODE 标记区域内写代码! 如果写在标记外面,下次用 CubeMX 重新生成时会被覆盖清除。


存储器映射

STM32 采用 统一编址 方式,将 Flash、SRAM、外设寄存器全部映射到 4GB 的地址空间中:

地址范围 用途 说明
0x0000 0000 ~ 0x07FF FFFF 启动区域 根据 BOOT 引脚映射到 Flash 或 SRAM
0x0800 0000 ~ 0x0807 FFFF Flash 存放程序代码(掉电不丢失)
0x2000 0000 ~ 0x2000 FFFF SRAM 运行时变量(掉电丢失)
0x4000 0000 ~ 0x4002 3FFF 外设寄存器 GPIO、USART、TIM 等外设的控制寄存器
0xE000 0000 ~ 0xE00F FFFF 内核外设 NVIC、SysTick 等 Cortex-M 内核组件

理解寄存器地址

当我们写 GPIOC->ODR = 0x0001 时,本质上就是向地址 0x4001 100C 写入数据。标准库和 HAL 库只是帮我们把这些地址定义成了结构体和宏。


内容导航

本板块按 STM32 的核心外设模块组织,由浅入深:

章节 核心内容 你将学到
时钟系统 RCC、时钟树、HSI/HSE/PLL 理解 STM32 的"心跳",学会配置系统时钟
GPIO 引脚模式、输入输出、复用 点灯、按键检测、理解推挽/开漏
中断系统 NVIC、EXTI、中断优先级 响应外部事件,理解抢占与响应优先级
定时器 基本/通用/高级定时器、PWM 精确定时、产生 PWM 波形驱动电机和舵机
通信协议 UART、SPI、I2C 与传感器、模块、PC 进行数据通信
ADC 与 DAC 模数转换、数模转换 采集传感器模拟信号,输出模拟电压
DMA 直接内存访问 不占用 CPU 搬运大量数据,提高系统效率