GPIO配置详解
本文系统讲解 STM32 GPIO(通用输入输出)的工作原理、8种模式、寄存器配置及标准库使用方法。
一、GPIO 是什么
GPIO 是 General Purpose Input Output 的缩写,即通用输入输出端口。它是 MCU 与外部世界交互的最基本接口,可以:
- 输入模式:读取外部信号(按键、传感器电平)
- 输出模式:驱动外部设备(LED、继电器、蜂鸣器)
- 复用功能:连接片上外设(UART、SPI、I2C 等)
二、GPIO 基本结构
2.1 典型 GPIO 内部结构
STM32 GPIO 内部结构包含以下几部分:
┌─────────────────────────────────────┐
│ VDD (上拉时) │
│ ↑ │
│ ┌────┴────┐ │
│ │ 上拉电阻 │ │
│ └────┬────┘ │
│ ↑ │
─────┤───→ 保护二极管 │ I/O引脚 │ ──────┼─────→ 外部线路
│ ┌────┴────┐ │
│ │ 下拉电阻 │ │
│ └────┬────┘ │
│ ↓ │
│ VSS (下拉时) │
└─────────────────────────────────────┘
↓
┌───────────────────────┐
│ 施密特触发器 │
│ (信号整形) │
└───────────┬───────────┘
↓
┌───────────── ──────────┐
│ 输入数据寄存器 │
│ (GPIOx_IDR) │
└───────────────────────┘
┌───────────────────────┐
│ 输出数据寄存器 │
│ (GPIOx_ODR) │
└───────────┬───────────┘
↓
┌───────────────────────┐
│ 位设置/清除寄存器 │
│ (GPIOx_BSRR/BRR) │
└───────────┬───────────┘
↓
┌───────────────────────┐
│ 输出控制单元 │
│ (推挽/开漏控制) │
└───────────────────────┘
2.2 保护二极管作用
每个 GPIO 引脚内部有两个保护二极管:
- 上方二极管:将过高电压钳制到 VDD,防止正极过压损坏芯片
- 下方二极管:将过低电压钳制到 VSS,防止负压损坏芯片
正常使用时:引脚电压应被钳制在 VSS 和 VDD 之间(0~3.3V)。
三、GPIO 8种工作模式
STM32 GPIO 有 8 种工作模式,分为两大类:输入模式和输出模式。
3.1 输入模式(4种)
| 模式 | 配置值 | 说明 |
|---|---|---|
| 浮空输入 | 00 | 引脚悬空,电平由外部电路决定 |
| 上拉输入 | 01 | 内部接上拉电阻,默认高电平 |
| 下拉输入 | 10 | 内部接下拉电阻,默认低电平 |
| 模拟输入 | 11 | 关闭施密特触发器,用于ADC |
3.1.1 浮空输入(Input Floating)
引脚 ──→ 施密特触发器 ──→ IDR寄存器
↑
引脚悬空
特点:
- 引脚未接任何内部电阻
- 电平完全由外部电路决定
- 优点:功耗低,适合低功耗设计
- 缺点:引脚悬空时电平不确定,易受干扰
- 适用场景:外部电路能明确提供稳定电平的情况
配置方法:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
3.1.2 上拉输入(Input Pull-Up)
引脚 ──→ 上拉电阻(约40kΩ) ──→ VDD
│
↓
施密特触发器 ──→ IDR寄存器
↑
引脚
特点:
- 内部接上拉电阻到 VDD(3.3V)
- 无外部信号时,引脚默认读取为高电平
- 适用场景:检测按键按下(按键另一端接地,按下为低电平)
配置方法:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // IPU = Input Pull-Up
GPIO_Init(GPIOA, &GPIO_InitStructure);
3.1.3 下拉输入(Input Pull-Down)
引脚 ──→ 下拉电阻(约40kΩ) ──→ VSS
│
↓
施密特触发器 ──→ IDR寄存器
↑
引脚
特点:
- 内部接下拉电阻到 VSS(GND)
- 无外 部信号时,引脚默认读取为低电平
- 适用场景:检测高电平有效的信号
配置方法:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // IPD = Input Pull-Down
GPIO_Init(GPIOA, &GPIO_InitStructure);
3.1.4 模拟输入(Input Analog)
特点:
- 关闭施密特触发器
- 引脚直接连接到片上 ADC
- 用于模拟信号采集(电压检测)
- 功耗最低
配置方法:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // AIN = Analog Input
GPIO_Init(GPIOA, &GPIO_InitStructure);
3.2 输出模式(4种)
| 模式 | 配置值 | 说明 |
|---|---|---|
| 推挽输出 | 01 | 能输出高/低电平,驱 动能力强 |
| 开漏输出 | 11 | 只能输出低电平,需外接上拉 |
| 复用推挽输出 | 10 | 由片上外设控制,推挽方式 |
| 复用开漏输出 | 11 | 由片上外设控制,开漏方式 |
3.2.1 推挽输出(Output Push-Pull)
┌──── VDD
│ │
────┤ P-MOS │────→ 高电平输出
│ │
引脚 │
────┤ N-MOS │────→ 低电平输出
│ │
└─── VSS
工作原理:
- 输出高电平:P-MOS 导通,N-MOS 截止,输出接近 VDD
- 输出低电平:P-MOS 截止,N-MOS 导通,输出接近 VSS
特点:
- 驱动能力强(通常 20~25mA,可直接驱动 LED)
- 能主动输出高电平也能主动输出低电平
- 缺点:两个电平互相“拉扯",不宜直接并联
配置方法:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // Out Push-Pull
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);