GPIO 概述
- STM32F407 系列微控制器拥有多个 GPIO 端口 (如 GPIOA 至 GPIOI),每个端口通常有16个引脚。

- 主要配置寄存器及其功能:
GPIOx_MODER | IO口模式设置 (输入、输出、复用、模拟) |
GPIOx_OTYPER | 输出类型设置 (推挽、开漏) |
GPIOx_OSPEEDR | 输出速度设置 |
GPIOx_PUPDR | 上拉或下拉设置 |
GPIOx_IDR | 输入数据寄存器 (只读) |
GPIOx_ODR | 输出数据寄存器 (可读写) |
GPIOx_BSRR | 位设置/复位寄存器 (只写,用于原子操作设置或清除位) |
GPIOx_AFRL/H | 复用功能选择寄存器低位和高位 |
GPIO 模式寄存器 (GPIOx_MODER
)❗
- 每个 GPIO 引脚使用2个位在
GPIOx_MODER
寄存器中进行配置。
配置值 | 模式 | 说明 |
00 | 输入模式 | 复位状态 |
01 | 通用输出模式 | 常规 GPIO 输出 |
10 | 复用功能模式 | 连接片上外设 |
11 | 模拟模式 | 用于 ADC/DAC |

由于每一个GPIO口通常有16个引脚,,所以GPIOx_MODER是一个32位寄存器;
GPIO 结构
- 5V 容忍 I/O 端口位的基本结构包括输入路径 (保护二极管、上拉/下拉电阻、TTL 施密特触发器) 和输出路径 (输出数据寄存器或BSRR控制P-MOS和N-MOS管)。

通用 IO 口初始化程序 (库函数编程)❗
- 定义
GPIO_InitTypeDef
类型的结构体变量。
- 填充结构体成员:
GPIO_Mode
,GPIO_Speed
,GPIO_OType
,GPIO_PuPd
,GPIO_Pin
。
- 调用
GPIO_Init()
函数完成初始化。
通用 IO 口操作 (库函数编程)❗
- 清零指定引脚 (设置低电平):
GPIO_ResetBits(GPIOA, GPIO_Pin_9);
(等效GPIOA->BSRRH = GPIO_Pin_9;
)。
- 置位指定引脚 (设置高电平):
GPIO_SetBits(GPIOA, GPIO_Pin_9);
(等效GPIOA->BSRRL = GPIO_Pin_9;
)。
- 设置GPIO口不通过 ODR 寄存器操作而用 BSRRH/BSRRL 寄存器的原因是 BSRR 提供原子操作,避免在中断或多任务环境中的读-修改-写竞态问题。
GPIO 端口置位/复位寄存器 (GPIOx_BSRR
)❗❗
这个 32 位寄存器被巧妙地分为两部分:
- 低 16 位(BSy):置位位
- 位 15:0(BSy):这些位用于将对应的 GPIO 端口输出数据寄存器(ODRx)的位设置为 1。
- 操作方式: 向
BSy
区域的某一位写入 1 时,对应的ODRx
位就会被设置为 1。写入 0 则不会对ODRx
位产生任何影响。
- 高 16 位(BRy):复位位
- 位 31:16(BRy):这些位用于将对应的 GPIO 端口输出数据寄存器(ODRx)的位设置为 0。
- 操作方式: 向
BRy
区域的某一位写入 1 时,对应的ODRx
位就会被设置为 0。写入 0 则不会对ODRx
位产生任何影响。
关键特性:
- 只写形式:
GPIOx_BSRR
寄存器是只写形式的。这意味着您不能直接读取它的值来判断当前 GPIO 的状态(读取会返回 0x0000 0000)。
- 原子操作: 这是 BSRR 寄存器的核心优势。通过写入 BSRR,您可以原子地修改一个或多个 GPIO 引脚的状态,无需先读取 ODR 寄存器的当前值,再修改,最后写回。这避免了在读-改-写(Read-Modify-Write)过程中可能出现的竞争条件(Race Condition
- 优先级: 如果同时对
BSx
和BRx
置位(即在同一个 32 位写入操作中,既尝试置位某个引脚,又尝试复位同一个引脚),BSx
的优先级更高,该引脚最终会被设置为 1。
- 32 位写入: 尽管分为高 16 位和低 16 位,但通常建议进行 32 位写入操作,以确保原子性。
示例代码
通过
GPIOx_BSRR
寄存器,Cortex-M 处理器提供了高效且安全的 GPIO 输出控制方式,尤其推荐在需要确保操作原子性的场景中使用。GPIO 的复用功能
- GPIO引脚可配置为复用功能 (AF),连接到片上外设。
- 配置寄存器:
GPIOx_AFRL
(引脚0-7) 和GPIOx_AFRH
(引脚8-15)。每个引脚用4位选择 AF0-AF15。具体映射需查阅芯片数据手册。