一、含义
GPIO代表通用输入/输出,是一种用于与外部设备通信的通用接口。
在嵌入式系统中,GPIO通常是一组可以配置为输入或输出的引脚,用于与外部电子元件(如传感器、执行器、LED等)进行数字通信。
| 模式分类 | 工作模式 | 典型功能 / 说明 |
|---|---|---|
| 输出模式 | 推挽输出 | 输出高电平为 VCC,低电平为 GND,驱动能力强 |
| 开漏输出 | 输出高电平需外部上拉电阻,可实现线与功能 | |
| 输入模式 | 上拉输入 | 内部上拉电阻接 VCC,无信号时为高电平 |
| 下拉输入 | 内部下拉电阻接 GND,无信号时为低电平 | |
| 浮空输入 | 无上下拉,电平由外部电路决定,易受干扰 | |
| 模拟模式 | 模拟输入/输出 | 用于 ADC(采样模拟电压)和 DAC(输出模拟电压) |
| 复用模式 | 复用功能 | 引脚由片上外设控制,如 USART、I²C、SPI 等 |
二、输入模式
GPIO输入模式常用来检查芯片外部IO引脚的状态,
外部电压经过TTL施密特触发器之后,将输出逻辑,最终写于GPIO寄存器。
2.1 TTL施密特触发器
| 项目 | 参数 / 说明 |
|---|---|
| 基本功能 | 整形电路,将输入信号整形为方波信号 |
| 正向阈值电压(上触发点) | 2.31V(0.7 × VDD,适用于 1.7V ≤ VDD ≤ 3.6V) |
| 负向阈值电压(下触发点) | 0.99V(0.3 × VDD,适用于 1.7V ≤ VDD ≤ 3.6V) |
| 逻辑规则 | • 输入电压 > 正向阈值 → 输出高电平(1) • 输入电压 < 负向阈值 → 输出低电平(0) |
| 5V 容忍输入电压范围 | -0.3V ~ 5.5V(适用于 2V ≤ VDD ≤ 3.6V) |
| 输出信号类型 | 数字信号(1 / 0) |
2.2 各个模式
| 输入模式 | 内部电阻 | 默认电平 | 典型应用 | 说明 |
|---|---|---|---|---|
| 浮空输入 | 无上拉/下拉 | 高阻态(不确定) | 检测外部真实电平(如按键、外部信号) | 引脚处于高阻状态,电平完全由外部电路决定,易受干扰 |
| 上拉输入 | 内部上拉电阻 | 高电平 | 检测外部信号是否为低电平 | 默认高电平,外部拉低时检测到低电平 |
| 下拉输入 | 内部下拉电阻 | 低电平 | 检测外部信号是否为高电平 | 默认低电平,外部拉高时检测到高电平 |
三、输出模式
GPIO控制器输出模式,主要是由P-MOS管和N-MOS管组成的一个结构单元。
当P-MOS管和N-MOS管同时工作,可组成推挽输出模式
当只有N-MOS管工作时,可组成开漏输出模式
3.1 推挽输出
| 项目 | 说明 |
|---|---|
| 命名依据 | 根据 P-MOS 和 N-MOS 管的工作方式命名 |
| 输入低电平时 | P-MOS 管导通,N-MOS 管截止 → 对外输出高电平 |
| 输入高电平时 | P-MOS 管截止,N-MOS 管导通 → 对外输出低电平 |
| 驱动能力 | 强(可直接输出高电平和低电平) |
| 是否需要外部上拉电阻 | 不需要 |
| 典型应用 | 驱动 LED、数字信号输出、普通 I/O 通信 |

3.2 开漏输出
| 项目 | 说明 |
|---|---|
| P-MOS 管状态 | 不论输入高低,始终处于关闭状态 |
| 输入高电平时 | N-MOS 管导通 → 输出为低电平 |
| 输入低电平时 | N-MOS 管截止 → 输出为高阻态(既非高电平也非低电平) |
| 输出高电平条件 | 必须外接上拉电阻,由上拉电阻提供高电平 |
| 是否需要外部上拉电阻 | 需要(如需输出高电平) |
| 线与逻辑说明 | 当多个开漏输出引脚并联时: • 所有设备都输出高电平 (高阻态+上拉)→ 总线为高电平 • 任一设备输出低电平 (N-MOS导通)→ 总线被拉低电平 • 这种机制方便实现总线仲裁 和同步通信 |
| 典型应用 | I²C 总线、SMBus、多设备共享线路(需线与功能的场景) |

3.2.1 ODR与BSRR寄存器
| 对比项 | ODR 寄存器 | BSRR 寄存器 |
|---|---|---|
| 定义 | 输出数据寄存器(Output Data Register) | 端口位设置/复位寄存器(Bit Set/Reset Register) |
| 作用 | 控制 GPIO 引脚的输出电平状态(高/低) | 实现原子操作方式设置或清除 GPIO 引脚状态 |
| 基本功能 | • 写 1 → 对应引脚输出高电平 • 写 0 → 对应引脚输出低电平 • 可读回当前输出值 | • 低16位写 1 → 对应引脚输出高电平 • 高16位写 1 → 对应引脚输出低电平 • 写 0 无效,不影响其他引脚 |
| 工作原理 | 读‑改‑写 : 1. 读取整个 ODR 值 2. 修改其中特定位 3. 将修改后的值写回 ODR | 直接写 : 1. 软件准备好要置位/复位的位掩码 2. 一次性写入 BSRR 3. 硬件自动完成对应引脚的电平改变 |
| 是否支持读取 | 支持(可读取当前输出状态) | 不支持(只写寄存器,读返回无效数据) |
| 操作原子性 | 非原子(读‑改‑写之间可能被中断破坏) | 原子(一次写入,硬件一次性完成) |
| 对其它引脚影响 | 有风险(修改一位时必须回写整个寄存器,可能误改其它位) | 无影响(只改变被写 1 的位,其他引脚维持原状) |
| 硬件实现 | 一个锁存器,直接连到输出驱动电路 | 两个锁存器/触发器(一个用于置位,一个用于复位),输出由两个触发器的状态决定 |
ODR 是整体覆盖写入,修改部分引脚时必须先读取全部状态来保护其他引脚;BSRR 是独立脉冲控制,置高和置低分开,永远不需要读取当前状态,因此混合操作也能一步原子完成。
四、模拟与复用模式
| 对比项 | 复用模式 | 模拟模式 |
|---|---|---|
| 控制主体 | 对应的外设控制器(如 USART、I²C、SPI、定时器等) | ADC 控制器 / DAC 控制器 |
| 工作原理 | 将 IO 引脚设置为复用模式后,管脚状态的控制不再由 GPIO 控制器控制,而是由对应的外设控制器进行状态控制 | IO 引脚上的模拟电压在 GPIO 部分不做任何处理,直接输入到芯片内部的 ADC 控制器进行采样处理 |
| 信号类型 | 数字信号(0 或 1) | 模拟信号(连续电压值) |
| 是否经过施密特触发器 | 是(输入路径) | 否(直通 ADC) |
| 引脚状态 | 由外设决定(高/低电平) | 高阻态,电压值由外部模拟电路决定 |
| 典型应用 | USART、I²C、SPI、PWM、定时器输入捕获、外部中断等 | ADC 模拟电压采集、DAC 模拟电压输出 |
| 配置要点 | 需将引脚映射到对应的复用功能(AF) | 需配置为模拟模式,引脚连接 ADC/DAC 通道 |
五、GPIO寄存器映射
5.1 GPIO 各组寄存器基址
| GPIO 组 | 寄存器基址 |
|---|---|
| GPIOA | 0x40020000 |
| GPIOB | 0x40020400 |
| GPIOC | 0x40020800 |
| GPIOD | 0x40020C00 |
| GPIOE | 0x40021000 |
| GPIOF | 0x40021400 |
| GPIOG | 0x40021800 |
| GPIOH | 0x40021C00 |
| GPIOI | 0x40022000 |
规律 :每组 GPIO 寄存器地址间隔 0x400(1024 字节)
5.2 GPIO 寄存器映射(偏移地址)
| 寄存器名称 | 缩写 | 偏移地址 | 功能描述 |
|---|---|---|---|
| GPIO 端口模式寄存器 | GPIOx_MODER | 0x00 | 配置引脚模式(输入/输出/复用/模拟) |
| GPIO 端口输出类型寄存器 | GPIOx_OTYPER | 0x04 | 配置输出类型(推挽/开漏) |
| GPIO 端口输出速度寄存器 | GPIOx_OSPEEDR | 0x08 | 配置输出速度(低速/中速/高速/超高速) |
| GPIO 端口上拉/下拉寄存器 | GPIOx_PUPDR | 0x0C | 配置上拉/下拉电阻(上拉/下拉/浮空) |
| GPIO 端口输入数据寄存器 | GPIOx_IDR | 0x10 | 读取引脚输入电平状态(只读) |
| GPIO 端口输出数据寄存器 | GPIOx_ODR | 0x14 | 控制引脚输出电平(可读可写) |
| GPIO 端口置位/复位寄存器 | GPIOx_BSRR | 0x18 | 原子操作置高/置低引脚(只写) |
| GPIO 复用功能低位寄存器 | GPIOx_AFRL | 0x20 | 配置引脚 0~7 的复用功能 |
| GPIO 复用功能高位寄存器 | GPIOx_AFRH | 0x24 | 配置引脚 8~15 的复用功能 |
基址与偏移的使用方法
某个具体寄存器的地址 = 该组基址 + 偏移地址
**六、**HAL库接口
6.1 GPIO引脚初始化配置结构体
cs
typedef struct
{
uint32_t Pin; /* 要配置的 GPIO 引脚 */
uint32_t Mode; /* GPIO 引脚的工作模式 */
uint32_t Pull; /* GPIO 引脚是否使用上、下拉电阻 */
uint32_t Speed; /* GPIO 引脚电平反转速度 */
uint32_t Alternate; /* GPIO 引脚复用模式 */
} GPIO_InitTypeDef;
6.2 GPIO引脚状态
cs
typedef enum
{
GPIO_PIN_RESET = 0, /* 低电平状态 */
GPIO_PIN_SET /* 高电平状态 */
} GPIO_PinState;
6.3 HAL_GPIO_Init函数
| 项目 | 说明 |
|---|---|
| 函数功能 | 初始化 GPIO 控制器 |
| 函数原型 | void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) |
| 参数 GPIOx | GPIO 组控制器基址(如 GPIOA、GPIOB 等) |
| 参数 GPIO_Init | GPIO 引脚模式配置(引脚号、模式、上下拉、速度、复用功能等) |
| 返回值 | 无 |
6.4 HAL_GPIO_ReadPin函数
| 项目 | 说明 |
|---|---|
| 函数功能 | 读取 GPIO 端口电平状态 |
| 函数原型 | GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) |
| 参数 GPIOx | GPIO 组控制器基址(如 GPIOA、GPIOB 等) |
| 参数 GPIO_Pin | GPIO 组内引脚(如 GPIO_PIN_0、GPIO_PIN_1 等) |
| 返回值 | GPIO 引脚状态(GPIO_PIN_RESET 低电平 / GPIO_PIN_SET 高电平) |
6.5 HAL_GPIO_WritePin函数
| 项目 | 说明 |
|---|---|
| 函数功能 | 设置 GPIO 端口电平状态 |
| 函数原型 | void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) |
| 参数 GPIOx | GPIO 组控制器基址(如 GPIOA、GPIOB 等) |
| 参数 GPIO_Pin | GPIO 组内引脚(如 GPIO_PIN_0、GPIO_PIN_1 等) |
| 参数 PinState | 要设置的状态(GPIO_PIN_RESET 低电平 / GPIO_PIN_SET 高电平) |
| 返回值 | 无 |
6.6 HAL_GPIO_TogglePin函数
| 项目 | 说明 |
|---|---|
| 函数功能 | 反转 GPIO 端口电平状态 |
| 函数原型 | void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) |
| 参数 GPIOx | GPIO 组控制器基址(如 GPIOA、GPIOB 等) |
| 参数 GPIO_Pin | GPIO 组内引脚(如 GPIO_PIN_0、GPIO_PIN_1 等) |
| 返回值 | 无 |