系列一: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;
}
相关推荐
ebiobiz8 小时前
Zig 嵌入式底层库选择与 build.zig 组织指南
c语言·c++·嵌入式硬件·mcu
Zw-awa16 小时前
反馈:让系统知道自己做得对不对
stm32
女神下凡19 小时前
芯参谋(38):NAND_MCP_电路设计指南
arm开发·单片机·嵌入式硬件·设计规范
嵌入式学习菌19 小时前
FreeRTOS 中断管理实战:BASEPRI 寄存器实验
单片机·嵌入式硬件
HRTOS20 小时前
HRTOS:一个名字背后的目标——不断逼近硬实时
经验分享·单片机·系统架构·51单片机
UrSpecial1 天前
GPIO 是什么?
单片机·嵌入式硬件
剑指offer.1 天前
ARM裸机开发-SPI
arm开发·嵌入式硬件·嵌入式·arm
修船大队长1 天前
配置接受报文每个报文对应一个mailbox配置流程记录
网络·单片机·mcu
搁浅小泽1 天前
二极管选型技术规范
单片机·嵌入式硬件·汽车
搁浅小泽1 天前
电感选型技术规范
单片机·嵌入式硬件·汽车