系列一:STM32 外设初始化

一、为什么 STM32 外设都需要初始化?

STM32 内部不仅有 CPU,还集成了大量外设:

复制代码
GPIO、USART、ADC、CAN、DMA、RTC、定时器、FSMC......

这些外设复位后通常不会自动按照我们的需求工作。程序必须告诉芯片:

复制代码
我要使用哪个外设
外设连接到哪些引脚
采用什么工作模式
运行速度是多少
是否使用中断或DMA
什么时候正式启动

因此,所谓"初始化",本质上就是:

将外设从复位后的默认状态,配置成当前项目需要的工作状态。

大多数 STM32 外设初始化,都可以概括为以下流程:

复制代码
确认硬件连接
    ↓
开启相关时钟
    ↓
配置GPIO及复用功能
    ↓
复位外设并清除旧状态
    ↓
配置外设核心参数
    ↓
配置DMA、过滤器或中断
    ↓
清除状态标志
    ↓
使能外设
    ↓
进行最小功能测试

二、第一步永远是看硬件连接

写初始化代码前,不能只看函数名,首先要看原理图和芯片手册。

例如 USART3 使用:

复制代码
PB10 → USART3_TX
PB11 → USART3_RX

ADC 电位器使用:

复制代码
PB1 → ADC1_IN9

CAN2 使用:

复制代码
PB13 → CAN2_TX
PB12 → CAN2_RX

液晶屏可能使用:

复制代码
D0~D15
CS、WR、RD、DC
RST、BK

三、为什么所有外设都要先开时钟?

STM32 为了降低功耗,复位后通常关闭大部分外设时钟。

例如使用 GPIOB 前要执行:

复制代码
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

使用 USART3 前要执行:

复制代码
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

使用 ADC1 前要执行:

复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

RCC 全称:

复制代码
Reset and Clock Control
复位与时钟控制

它相当于 STM32 内部的"时钟和复位管理中心"。

可以把开启时钟理解成:

复制代码
RCC开时钟:给外设接通电源
初始化寄存器:设置外设工作方式
外设使能:按下启动按钮

四、如何判断使用 AHB1、APB1 还是 APB2?

不同外设挂在不同总线上。

常见关系如下:

总线 常见外设
AHB1 GPIO、DMA、CRC
APB1 USART2/3、UART4/5、CAN、PWR、I²C
APB2 USART1/6、ADC、SPI1、部分高级定时器
AHB3 FSMC

所以:

复制代码
GPIOB  → RCC_AHB1PeriphClockCmd()
USART3 → RCC_APB1PeriphClockCmd()
ADC1   → RCC_APB2PeriphClockCmd()
FSMC   → RCC_AHB3PeriphClockCmd()

初始化时函数用错总线,外设通常不会工作。

五、如何判断使用 AHB1、APB1 还是 APB2?

不同外设挂在不同总线上。

常见关系如下:

总线 常见外设
AHB1 GPIO、DMA、CRC
APB1 USART2/3、UART4/5、CAN、PWR、I²C
APB2 USART1/6、ADC、SPI1、部分高级定时器
AHB3 FSMC

所以:

复制代码
GPIOB  → RCC_AHB1PeriphClockCmd()
USART3 → RCC_APB1PeriphClockCmd()
ADC1   → RCC_APB2PeriphClockCmd()
FSMC   → RCC_AHB3PeriphClockCmd()

初始化时函数用错总线,外设通常不会工作。

六、初始化函数的通用逻辑

复制代码
int Peripheral_Init(void)
{
    /* 1. 定义并初始化配置结构体 */
    GPIO_InitTypeDef GPIO_InitStructure;
    Peripheral_InitTypeDef InitStructure;

    GPIO_StructInit(&GPIO_InitStructure);
    Peripheral_StructInit(&InitStructure);

    /* 2. 开启GPIO和外设时钟 */
    RCC_xxxPeriphClockCmd(GPIO_CLK, ENABLE);
    RCC_xxxPeriphClockCmd(PERIPHERAL_CLK, ENABLE);

    /* 3. 配置GPIO */
    GPIO_InitStructure.GPIO_Pin = PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(PORT, &GPIO_InitStructure);

    /* 4. 配置AF映射 */
    GPIO_PinAFConfig(PORT, PIN_SOURCE, GPIO_AF_xxx);

    /* 5. 复位外设 */
    RCC_xxxPeriphResetCmd(PERIPHERAL_CLK, ENABLE);
    RCC_xxxPeriphResetCmd(PERIPHERAL_CLK, DISABLE);

    /* 6. 配置外设核心参数 */
    InitStructure.xxx = xxx;
    Peripheral_Init(PERIPHERAL, &InitStructure);

    /* 7. 清除状态标志 */
    Peripheral_ClearFlag(PERIPHERAL, FLAGS);

    /* 8. 配置中断或DMA */
    /* ... */

    /* 9. 使能外设 */
    Peripheral_Cmd(PERIPHERAL, ENABLE);

    /* 10. 检查是否启动成功 */
    return 0;
}
相关推荐
XiangrongZ2 小时前
debian中配置stm32的交叉编译环境
运维·stm32·debian
zcmodeltech2 小时前
钢铁冶金沙盘模型多工序协同控制系统设计:基于STM32与Modbus RTU的高炉-连铸-热轧全流程联动方案
stm32·单片机·嵌入式硬件·数据库架构·嵌入式实时数据库·多分类
西城微科方案开发3 小时前
充气泵PCBA方案:数字传感器VS模拟传感器
单片机
zcmodeltech4 小时前
供热系统模型多工况控制系统设计:基于STM32与Modbus RTU的热源-管网-末端联动方案
大数据·stm32·单片机·嵌入式硬件·制造·数据库系统
时空自由民.4 小时前
STM32的缓存Cache
stm32·嵌入式硬件·缓存
智闲电子设计5 小时前
STM32 定时器 PWM 实战:从呼吸灯到舵机控制
c语言·stm32·单片机·嵌入式硬件·学习
azwsm13 小时前
驱动第一阶段——启动流程
单片机·嵌入式硬件
单片机杂货铺15 小时前
基于单片机的自动开窗器设计
stm32·嵌入式硬件·51单片机·硬件工程
天天爱吃肉821817 小时前
商用车多体动力学实战笔记|第6篇:动力传动系统(发动机、变速箱、分动器、TCS、LSD限滑差速)
大数据·人工智能·笔记·python·嵌入式硬件·汽车