文章目录
- 一、GPIO简介
- 二、GPIO模块详解
-
- [ 1、GPIO框图](# 1、GPIO框图)
-
- [ 1.保护二极管](# 1.保护二极管)
- [ 2.P-MOS管和N-MOS管](# 2.P-MOS管和N-MOS管)
- [ 3.输出数据寄存器(Output Data Register ODR)](# 3.输出数据寄存器(Output Data Register ODR))
- [ 4.复用功能输出](# 4.复用功能输出)
- [ 5.输入数据寄存器(Input Data Register IDR)](# 5.输入数据寄存器(Input Data Register IDR))
- [ 6.复用功能输入](# 6.复用功能输入)
- [ 7.模拟输入输出](# 7.模拟输入输出)
- [ 2、工作模式](# 2、工作模式)
-
- [ 1.输入模式(4 种)](# 1.输入模式(4 种))
- [ 2.输出模式(4 种)](# 2.输出模式(4 种))
- [ 3、GPIO速度](# 3、GPIO速度)
- 三、CudeMx配置GPIO
-
- [ 1、GPIO输出(LED 示例:PB5)](# 1、GPIO输出(LED 示例:PB5))
-
- [ 1.选中引脚](# 1.选中引脚)
- [ 2.详细配置(左侧 System Core → GPIO)](# 2.详细配置(左侧 System Core → GPIO))
- [ 2、GPIO 输入(按键示例:PC13,上拉)](# 2、GPIO 输入(按键示例:PC13,上拉))
-
- [ 1.选中引脚](# 1.选中引脚)
- [ 2.详细配置](# 2.详细配置)
- [ 3、GPIO 外部中断(EXTI,按键 PA0)](# 3、GPIO 外部中断(EXTI,按键 PA0))
-
- [ 1.选中引脚](# 1.选中引脚)
- [ 2.配置触发与上下拉](# 2.配置触发与上下拉)
- [ 3.使能 NVIC 中断](# 3.使能 NVIC 中断)
- [ 4、时钟配置(必做)](# 4、时钟配置(必做))
- [ 5、生成代码](# 5、生成代码)
- [ 6、添加代码](# 6、添加代码)
-
- [ 1.输出(LED)](# 1.输出(LED))
- [ 2.输入(按键)](# 2.输入(按键))
- [ 3.中断回调](# 3.中断回调)
- 四、GPIO模块组成
-
- 1、数据结构
- 2、句柄
- 3、API
-
- [ 1. 初始化](# 1. 初始化)
- [ 2. 读引脚](# 2. 读引脚)
- [ 3. 写引脚](# 3. 写引脚)
- [ 4. 翻转电平](# 4. 翻转电平)
- [ 5. 中断服务(EXTI)](# 5. 中断服务(EXTI))
- [ 6. 中断回调](# 6. 中断回调)
- [ 7.时钟使能](# 7.时钟使能)
- [ 8.模式定义](# 8.模式定义)
- [ 4、状态/错误](# 4、状态/错误)
-
- [ 1. 引脚电平状态 GPIO_PinState](# 1. 引脚电平状态 GPIO_PinState)
- [ 2. 中断挂起状态(EXTI 标志)](# 2. 中断挂起状态(EXTI 标志))
- 五、GPIO模块应用实例
-
- [ 1、推挽输出 --- 控制 LED(PB5)](# 1、推挽输出 — 控制 LED(PB5))
- [ 2、上拉输入 --- 按键(PC13)](# 2、上拉输入 — 按键(PC13))
一、GPIO简介
GPIO :General Purpose Input Output,通用输入输出引脚,是 MCU 与外部世界交互的最基本接口。
STM32F103 一般有 GPIOA ~ GPIOG,每组 16 个引脚(Pin0 ~ Pin15)。
二、GPIO模块详解
1、GPIO框图

1.保护二极管
引脚的两个保护二级管可以防止引脚外部过高或过低的电压输入,当引脚电压高于VDD时, 上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。
2.P-MOS管和N-MOS管

推挽输出:
所谓的推挽输出模式,是根据这两个MOS管的工作方式来命名的。
在该结构中输入高电平时,经过反向后,上方的P-MOS导通,下方的N-MOS关闭, 对外输出高电平;
在该结构中输入低电平时,经过反向后,N-MOS管导通,P-MOS关闭,对外输出低电平。
开漏输出 :
开漏输出模式时,上方的P-MOS管完全不工作。
如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出接地, 若控制输出为1 (它无法直接输出高电平)时,则P-MOS管和N-MOS管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。
注意:
开漏输出时,上拉电路自行另外加,VDD可自定义为5V。

3.输出数据寄存器(Output Data Register ODR)
输出数据寄存器GPIOx_ODR,修改输出寄存器的值就可以修改GPIO引脚的输出电平。
4.复用功能输出
复用功能输出"中的"复用"是指STM32的其它片上外设对GPIO引脚进行控制,此时GPIO引脚用作该外设功能的一部分,算是第二用途。
5.输入数据寄存器(Input Data Register IDR)
GPIO引脚经过内部的上、下拉电阻,可以配置成上/下拉输入,然后再连接到施密特触发器,信号经过触发器后, 模拟信号转化为0、1的数字信号,然后存储在"输入数据寄存器GPIOx_IDR"中,通过读取该寄存器就可以了解GPIO引脚的电平状态。
// 读取GPIOB端口的16位数据值
uint16_t temp;
temp = GPIOB->IDR;
6.复用功能输入
与"复用功能输出"模式类似,在"复用功能输入模式"时,GPIO引脚的信号传输到STM32其它片上外设,由该外设读取引脚状态。
7.模拟输入输出
当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号是不经过施密特触发器的,因为经过施密特触发器后信号只有0、1两种状态, 所以ADC外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。
2、工作模式
1.输入模式(4 种)
浮空输入(GPIO_Mode_IN_FLOATING)
引脚悬空时电平不确定。
常用于外部按键、中断引脚。
上拉输入(GPIO_Mode_IPU)
内部上拉电阻 → 默认高电平。
按键常用。
下拉输入(GPIO_Mode_IPD)
内部下拉电阻 → 默认低电平。
模拟输入(GPIO_Mode_AIN)
用于 ADC、DAC 等模拟功能。
关闭上 / 下拉,减少干扰。
2.输出模式(4 种)
推挽输出(GPIO_Mode_Out_PP)
可强输出高 / 低电平。
驱动 LED、继电器、器件引脚。
开漏输出(GPIO_Mode_Out_OD)
只能输出 低电平 / 高阻态。
高电平需外部上拉。
多用于 I2C、单线通信。
复用推挽(GPIO_Mode_AF_PP)
外设复用:UART_TX、SPI、PWM、MCO (PA8)。
复用开漏(GPIO_Mode_AF_OD)
外设开漏:I2C_SDA/SCL。
3、GPIO速度
只对输出模式有效,控制引脚翻转速率:
GPIO_Speed_2MHz 低速
GPIO_Speed_10MHz 中速
GPIO_Speed_50MHz 高速(MCO、PWM 用这个)
三、CudeMx配置GPIO
1、GPIO输出(LED 示例:PB5)
1.选中引脚
在芯片图上找到 PB5,左键点击 → 选择 GPIO_Output。

2.详细配置(左侧 System Core → GPIO)
选中 PB5,设置:
GPIO output level: High(默认灭)
GPIO mode: Output Push Pull(推挽)
Pull-up/Pull-down: No pull-up and no pull-down
Maximum output speed: Low

2、GPIO 输入(按键示例:PC13,上拉)
1.选中引脚
点击 PC13 → 选择 GPIO_Input。

2.详细配置
GPIO mode: Input mode
Pull-up/Pull-down: Pull-up

3、GPIO 外部中断(EXTI,按键 PA0)
1.选中引脚
点击 PA0 → 选择 GPIO_EXTI0。

2.配置触发与上下拉
GPIO mode: External Interrupt Mode with Falling edge trigger
Pull-up/Pull-down: Pull-up

3.使能 NVIC 中断
进入 NVIC Settings,勾选 EXTI line0 interrupt,设置优先级。

4、时钟配置(必做)
进入 Clock Configuration。
选外部晶振 HSE,配置 SYSCLK = 72 MHz(F103 标准)。
5、生成代码
进入 Project Manager:
填写工程名、路径
选择 IDE:MDK-ARM
点击 GENERATE CODE。
6、添加代码
1.输出(LED)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // 亮
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); // 翻转
2.输入(按键)
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET) {
// 按下
}
3.中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == GPIO_PIN_0) {
// 按键中断处理
}
}
四、GPIO模块组成
1、数据结构
初始化结构体:GPIO_InitTypeDef
作用:配置 GPIO 引脚的模式、速度、上下拉。
c
typedef struct
{
uint32_t Pin; // 引脚编号:GPIO_PIN_0 ~ 15
uint32_t Mode; // 模式(输入/输出/中断/复用)
uint32_t Pull; // 上下拉
uint32_t Speed; // 输出速度(仅输出有效)
} GPIO_InitTypeDef;
2、句柄
老版句柄:GPIO_HandleTypeDef hgpio;
新版没有句柄:
GPIO 没有句柄结构体!
直接用 GPIOx(GPIOA/GPIOB...)操作。
3、API

1. 初始化
HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
2. 读引脚
GPIO_PinState HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x);
3. 写引脚
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_SET/RESET);
4. 翻转电平
HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_x);
5. 中断服务(EXTI)
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_x);
6. 中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
7.时钟使能
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 使能GPIOB时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
// 关闭GPIOA时钟(极少用)
__HAL_RCC_GPIOA_CLK_DISABLE();
8.模式定义

4、状态/错误
1. 引脚电平状态 GPIO_PinState
GPIO_PIN_RESET // 低电平 0
GPIO_PIN_SET // 高电平 1
2. 中断挂起状态(EXTI 标志)
// 获取中断标志
__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_x)
// 清除中断标志
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_x)
五、GPIO模块应用实例
复用功能在对应的模块笔记。
1、推挽输出 --- 控制 LED(PB5)
c
// 开时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef gpio = {0};
gpio.Pin = GPIO_PIN_5;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &gpio);
// 输出低电平点亮LED
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
2、上拉输入 --- 按键(PC13)
c
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef gpio = {0};
gpio.Pin = GPIO_PIN_0;
gpio.Mode = GPIO_MODE_INPUT;
gpio.Pull = GPIO_PULLUP; // 上拉
HAL_GPIO_Init(GPIOC, &gpio);
// 读取:按下=低电平
if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
{
// 按键按下
}