GPIO 配置的核心要素

不管是哪种总线或功能,GPIO 配置都围绕以下几个关键点:

要素
说明
引脚号
确定使用哪个端口的哪个引脚(如 PA5、PB12)
模式(Mode)
输入 / 输出 / 复用功能 / 模拟
输出类型(Type)
推挽(Push-Pull)/ 开漏(Open-Drain)
上拉/下拉(Pull)
上拉、下拉、浮空
速度(Speed)
低速、中速、高速、超高速(影响驱动能力和功耗)
复用功能(Alternate Function)
当用作外设引脚时,需要指定对应的复用功能编号

通用配置步骤

步骤 1:使能 GPIO 端口时钟

在配置任何引脚前,必须先开启对应 GPIO 端口的时钟(以 ARM Cortex-M 为例):

__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能 GPIOA 时钟

步骤 2:选择引脚和模式

  • 普通输入:读取外部电平(按键、传感器等)
  • 普通输出:控制 LED、继电器等
  • 复用功能:作为 UART、SPI、I²C 等外设引脚
  • 模拟模式:用于 ADC 输入、DAC 输出

步骤 3:设置输出类型(仅输出模式有效)

  • 推挽输出:可输出高/低电平,驱动能力强
  • 开漏输出:只能输出低电平,高电平需上拉(常用于 I²C、线与逻辑)

步骤 4:配置上拉/下拉

  • 上拉:空闲时为高电平
  • 下拉:空闲时为低电平
  • 浮空:空闲电平不确定(易受干扰,不推荐用于输入)

步骤 5:配置速度

  • 速度越高,驱动能力越强,但功耗也越大

  • 一般:

    • 低速:≤2MHz
    • 中速:≤10MHz
    • 高速:≤50MHz
    • 超高速:≥100MHz

步骤 6:配置复用功能(如果需要)

  • 查看芯片数据手册,找到引脚对应的复用功能编号(AFx)
  • 在寄存器或 HAL 库中设置

常见模式配置示例(STM32 HAL 库)

普通推挽输出

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

上拉输入

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

复用推挽输出(如 UART TX)

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

复用开漏输出(如 I²C)

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

快速配置检查表

  • 确认引脚号和端口
  • 使能对应 GPIO 时钟
  • 选择正确的模式(输入/输出/复用/模拟)
  • 设置输出类型(推挽/开漏)
  • 配置上拉/下拉
  • 选择合适的速度
  • 如果是复用功能,配置正确的 Alternate Function

常见通信总线配置

UART(通用异步收发传输)

信号线

  • TX:发送数据(主机输出)
  • RX:接收数据(主机输入)
  • 可选:RTS、CTS(硬件流控)

GPIO 配置要点

  • TX:复用推挽输出(Alternate Function Push-Pull)
  • RX:复用输入(Alternate Function Input),建议上拉
  • 配置复用功能号(AFx)为对应的 UART/USART 外设
  • 输出速度可设为中速或高速(一般 10MHz 以上)

STM32 HAL 示例

// TX: PA9, RX: PA10
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();

// TX
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// RX
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

SPI(串行外设接口)

信号线

  • SCLK:时钟(主机输出)
  • MOSI:主机输出,从机输入(主机 → 从机数据)
  • MISO:主机输入,从机输出(从机 → 主机数据)
  • NSS/CS:片选(可选,高/低电平有效,主机输出)

GPIO 配置要点

  • SCLK:复用推挽输出
  • MOSI:复用推挽输出
  • MISO:复用输入(上拉/浮空均可,上拉更稳定)
  • NSS:可配置为复用推挽输出(硬件 NSS)或普通推挽输出(软件控制)
  • 输出速度一般设为高速(100MHz 或更高,视芯片而定)

STM32 HAL 示例

// SCLK: PA5, MOSI: PA7, MISO: PA6, NSS: PA4
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();

GPIO_InitTypeDef GPIO_InitStruct = {0};
// SCLK
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// MOSI
GPIO_InitStruct.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// MISO
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

// NSS (软件控制)
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // 初始拉高

I²C(Inter-Integrated Circuit)

信号线

  • SCL:时钟线(主机输出,双向开漏)
  • SDA:数据线(双向开漏)

GPIO 配置要点

  • SCL / SDA:复用开漏输出(Alternate Function Open-Drain)
  • 必须上拉(外部上拉电阻或内部上拉)
  • 输出速度一般低速(100kHz 模式)或高速(400kHz 模式)
  • 配置复用功能号为 I²C 外设

STM32 HAL 示例

// SCL: PB6, SDA: PB7
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();

GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;           // 开漏输出
GPIO_InitStruct.Pull = GPIO_PULLUP;               // 上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;      // 低速
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

对比总结表

总线
信号线
模式
上拉要求
速度
备注
UART
TX
复用推挽输出

中/高速
异步通信,点对点
UART
RX
复用输入
建议上拉
中速
异步通信,点对点
SPI
SCLK/MOSI
复用推挽输出

高速/超高速
同步,可多从机
SPI
MISO
复用输入
上拉可选
高速
同步,可多从机
SPI
NSS
推挽输出/复用输出
上拉可选
高速
片选信号
I²C
SCL/SDA
复用开漏输出
必须上拉
低速/高速
同步,多主多从

记忆口诀:

  • UART:TX 推挽、RX 上拉输入
  • SPI:SCLK/MOSI 推挽,MISO 输入,NSS 可软件控制
  • I²C:SCL/SDA 开漏 + 上拉,速率低但连线少