STM32:GPIO相关知识详解
·
一、GPIO 概述
GPIO(General Purpose Input/Output,通用输入/输出)是微控制器与外部世界交互的最基本、最常用的接口。GPIO是STM32的最基础的一种外设,STM32 系列微控制器提供了丰富且功能强大的 GPIO 端口,每个引脚都可以通过软件灵活配置为多种工作模式,以适应不同的应用场景,如驱动 LED、读取按键、通信接口等。
二、STM32中GPIO内部结构
理解 GPIO 的内部结构是掌握其配置和使用的关键。一个典型的 STM32 GPIO 引脚内部包含以下主要部分:

- 保护二极管:防止引脚电压过高或过低,起到钳位保护作用,其中应加上保护电阻来实现。
- 上拉/下拉电阻:可通过寄存器配置,在输入模式下为引脚提供确定的默认电平,其为弱上拉和弱下拉两种模式。
- 施密特触发器:TTL电路对输入信号进行整形,提高抗干扰能力,将模拟信号转换为数字信号。
- 输入驱动器:将外部信号送入输入数据寄存器。
- 输出驱动器:包含推挽(Push-Pull)和开漏(Open-Drain)两种结构,负责驱动外部负载。
- 复用功能选择器:将引脚连接到内部外设(如 USART、I2C、SPI 等)。
- 位设置/清除寄存器:BSRR用于原子操作,避免读-修改-写操作带来的风险。
这些部件通过一系列配置寄存器(如 GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, GPIOx_PUPDR)进行控制。
三、GPIO 工作模式详解
STM32 的每个 GPIO 引脚都可以独立配置为以下 8 种模式之一:
对于输入,只需要关注上图中的上半部分;对于输出部分,只需要重点关注上图中的下半部分。
1. 输入模式
- 浮空输入:引脚处于高阻态,IO的电平状态不确定,电平完全由外部电路决定。适用于通信总线(如 I2C)等。
- 上拉输入:内部上拉电阻使能,上拉电路打开,默认电平为高。适用于按键检测(按键接地)。
- 下拉输入:内部下拉电阻使能,下拉电路打开,默认电平为低。适用于按键检测(按键接电源)。
- 模拟输入:信号直接连接到 ADC 或 DAC,关闭了施密特触发器,电路从上方外设经过,用于采集模拟信号。
2. 输出模式
- 推挽输出:既可以输出高电平(接近 VDD),也可以输出低电平(接近 GND),具有较强的驱动能力。是最常用的输出模式。
- 开漏输出:p_mos始终是关,只能输出低电平或高阻态。高电平需要额外的外部上拉电阻提供。适用于电平转换和“线与”逻辑(如 I2C)。
3. 复用功能模式
- 复用推挽输出:引脚作为片上外设(如 SPI、USART)的输出脚,工作在推挽模式。
- 复用开漏输出:引脚作为片上外设的输出脚,工作在开漏模式。
输出模式还可以配置不同的输出速度(低速、中速、高速、超高速),以平衡功耗和信号完整性。
四、GPIO 相关寄存器
STM32 通过一组寄存器来控制 GPIO,主要寄存器如下:
- GPIOx_MODER:模式寄存器,配置引脚为输入、输出、复用或模拟模式。
- GPIOx_OTYPER:输出类型寄存器,配置为推挽或开漏输出。
- GPIOx_OSPEEDR:输出速度寄存器。
- GPIOx_PUPDR:上拉/下拉寄存器,选择上拉/下拉。
- GPIOx_IDR:输入数据寄存器,读取引脚电平状态。
- GPIOx_ODR:输出数据寄存器,控制引脚输出电平。
- GPIOx_BSRR:位设置/清除寄存器,用于原子操作,设置或清除 ODR 中的特定位。
- GPIOx_LCKR:配置锁定寄存器,锁定当前端口配置,防止意外修改。
- GPIOx_AFRL/AFRH:复用功能选择寄存器,选择引脚连接到哪个片上外设。
五、GPIO 使用注意事项
- 未用引脚处理:建议配置为模拟输入模式并内部上拉/下拉,以降低功耗和噪声。
- 驱动能力:推挽输出驱动电流有限,驱动大电流负载(如电机)需外加驱动电路。
- 电平兼容:连接 5V 器件时,需注意 STM32 引脚为 3.3V 电平,必要时使用电平转换电路或配置为开漏模式加上拉。
- 初始化顺序:先开启 GPIO 端口时钟(RCC),再进行引脚配置。
- 复用功能:使用外设功能时,除了配置 GPIO 为复用模式,还需正确配置 AFRL/AFRH 寄存器。
六、代码示例:配置一个 LED 引脚
以下是一个使用 HAL 库配置 PC13 引脚为推挽输出,并控制 LED 闪烁的示例:
#include "stm32f1xx_hal.h"
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 1. 使能 GPIOC 时钟
__HAL_RCC_GPIOC_CLK_ENABLE();
// 2. 配置 PC13
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不上拉也不下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速输出
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
int main(void)
{
HAL_Init();
GPIO_Init();
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // 翻转 PC13 电平
HAL_Delay(500); // 延时 500ms
// 或者也可以是用下面的方法:
// HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
// delay_ms(500);
// HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
// delay_ms(500);
}
}
七、总结
STM32的GPIO是一个高度可配置的模块。通过合理配置,可以满足从简单的数字IO到复杂通信接口的各种需求。在实际项目中需结合数据手册和参考手册,使用特定的GPIO特性。
更多推荐

所有评论(0)