🎓 总站 🏠 本课目录 05 GPIO 06 中断 07 串口通信
智能嵌入式系统设计 · 第5章

通用输入输出 GPIO 模块

基于 STM32F103 · 零基础讲解 GPIO 结构、八种工作模式、标准外设库与 HAL 库点灯。

📚 学习进度
0%

🎯学习目标

  • 了解 GPIO 的基本概念;
  • 理解 STM32F103 的 GPIO 内部结构、工作模式和使用特性;
  • 理解 GPIO 的输入输出模式;
  • 熟悉 GPIO 相关的标准外设库函数和 HAL 库函数;
  • 掌握用标准库 / HAL 库实现 LED 灯闪烁。

1GPIO 概述

GPIO(General Purpose Input/Output,通用输入输出)端口内部由一个个寄存器组成:一个引脚对应一个寄存器位,改变寄存器中的数据就能改变外设的工作方式。

💡 一句话理解GPIO 就是单片机上"可编程控制高低电平"的引脚。写寄存器=控制引脚输出,读寄存器=读取引脚输入。

与 51 单片机相比,STM32 拥有更多 I/O 引脚、更强驱动能力、更灵活的控制方式,功能也更强大。

2引脚与内部结构

STM32F103ZET6 引脚分类(144 引脚,六大类)

类别引脚举例
电源引脚VDD、VSS、VREF+/-、VDDA、VSSA、VBAT
晶振引脚PC14、PC15、OSC_IN、OSC_OUT
复位引脚NRST
BOOT 引脚BOOT0、BOOT1
程序下载引脚PA13、PA14、PA15、PB3、PB4
GPIO 引脚7 组(PA~PG),每组 16 个:Px0~Px15
GPIO PA组 PB组 PC组 …PG组 每组16个引脚Px0 ~ Px15 每组7个寄存器控制16个引脚
图1 · GPIO 组织结构:7 组 × 16 引脚,每组由 7 个寄存器控制

大多数引脚还通过复用技术兼具其他专用功能(如串口、ADC、IIC 等)。

3八种工作模式 ⭐(核心考点)

STM32 的 GPIO 共有 8 种工作模式,分为输出输入两大类。点击卡片翻转查看要点:

📤 输出模式(4 种)

🔵

推挽输出

Push-Pull, PP
两个 MOS 管互补导通:输出高电平时 P-MOS 导通,低电平时 N-MOS 导通。驱动能力强、速度快,最常用
🟠

开漏输出

Open-Drain, OD
只有下拉 MOS 管、无上拉,漏极悬空。需外接上拉电阻用于电平转换、IIC 总线、线与
🔷

复用推挽

AF Push-Pull
推挽输出 + 复用功能(AFIO),引脚给片上外设用。如串口 TX、SPI
🔶

复用开漏

AF Open-Drain
开漏输出 + 复用功能。如 IIC 的 SCL/SDA

📥 输入模式(4 种)

⬆️

上拉输入

IPU
内部接上拉电阻,默认高电平无输入时读到 1
⬇️

下拉输入

IPD
内部接下拉电阻,默认低电平无输入时读到 0
🔘

浮空输入

Floating
既不上拉也不下拉,电平由外部决定。状态不确定,需外部确定电平
📊

模拟输入

Analog
施密特触发器关闭,不接上下拉,信号直连片上外设。典型用于 A/D 采集
⭐ 推挽 vs 开漏(必考)推挽:能主动输出高和低电平,驱动强,但不能"线与";开漏:只能拉低,输出高靠外部上拉电阻,可多设备"线与",适合 IIC 总线和电平转换。

4GPIO 输出速度

注意:输出速度不是信号速度,而是 I/O 口驱动电路的响应速度。STM32F103 有 3 档:

🐢

2 MHz

低速。LED、蜂鸣器等普通外设。功耗低。

🚶

10 MHz

中速。一般复用功能。

🚀

50 MHz

高速。IIC、SPI 等高速复用输出。

💡 选择原则结合实际选择:保证信号稳定的同时降低功耗。普通外设用 2MHz,高速复用用 10/50MHz。

5GPIO 寄存器(每组 7 个)

每组 GPIO 端口(Px)由 7 个寄存器组成,控制该端口 16 个引脚:

寄存器作用
CRL / CRH(配置低/高)配置每个引脚的模式和速度(低 8 位 / 高 8 位)
IDR(输入数据)读取引脚输入电平
ODR(输出数据)设置引脚输出电平
BSRR(位设置/复位)原子地置位/复位引脚(高 16 位复位,低 16 位置位)
BRR(位复位)原子地复位引脚
LCKR(锁定)锁定引脚配置

6标准外设库接口函数

源码在 stm32f10x_gpio.c,头文件 stm32f10x_gpio.h 声明了共 18 种库函数。

类型常用函数功能
初始化/复位GPIO_Init()按结构体参数初始化 GPIO
GPIO_DeInit()恢复默认复位值
引脚操作GPIO_SetBits()置位引脚(输出高)
GPIO_ResetBits()复位引脚(输出低)
GPIO_WriteBit()写指定引脚电平
GPIO_ReadInputDataBit()读输入引脚电平
外部中断GPIO_EXTILineConfig()配置端口为中断线输入

GPIO_Init() 有两个参数:① 端口 x(A~G);② 指向 GPIO_InitTypeDef 结构体的指针。结构体成员:

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;        // 引脚 0~15 或 All
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;  // 工作模式(推挽输出)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;   // 输出速度
GPIO_Init(GPIOA, &GPIO_InitStructure);

7标准库 vs HAL 库

对比标准外设库 (StdPeriph)HAL 库
抽象程度贴近寄存器,效率高高度抽象,跨系列可移植
初始化GPIO_Init()HAL_GPIO_Init()
写引脚GPIO_SetBits()/ResetBits()HAL_GPIO_WritePin()
翻转读 ODR 取反写回HAL_GPIO_TogglePin()
读引脚GPIO_ReadInputDataBit()HAL_GPIO_ReadPin()
配套工具手写STM32CubeMX 图形化生成

重点例题:LED 闪烁

例题:用标准库让 PA0 上的 LED 每 500ms 闪烁一次 思路:① 开 GPIOA 时钟 → ② 配 PA0 为推挽输出 → ③ 循环置位/复位 + 延时。
// ① 使能 GPIOA 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// ② 配置 PA0 推挽输出 2MHz
GPIO_InitTypeDef g;
g.GPIO_Pin=GPIO_Pin_0; g.GPIO_Mode=GPIO_Mode_Out_PP; g.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&g);
// ③ 主循环闪烁
while(1){
  GPIO_SetBits(GPIOA,GPIO_Pin_0);   delay_ms(500);  // 亮
  GPIO_ResetBits(GPIOA,GPIO_Pin_0); delay_ms(500);  // 灭
}
关键点:必须先开时钟(GPIO 挂在 APB2 总线),不开时钟配置无效;② LED 接法决定亮灭逻辑(共阳极时低电平亮)。
HAL 库等价写法
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef g={0};
g.Pin=GPIO_PIN_0; g.Mode=GPIO_MODE_OUTPUT_PP; g.Speed=GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA,&g);
while(1){ HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0); HAL_Delay(500); }

🎯自测(点击展开)

STM32F103 有几组 GPIO?每组几个引脚?
7 组(PA~PG),每组 16 个引脚(Px0~Px15)。
推挽输出和开漏输出有什么区别?
推挽能主动输出高低电平、驱动强;开漏只能拉低,输出高靠外部上拉,可"线与",适合 IIC 总线和电平转换。
"GPIO 输出速度"指的是什么?
指 I/O 口驱动电路的响应速度,不是信号速度。有 2/10/50MHz 三档。
配置 GPIO 前必须先做什么?
使能对应 GPIO 端口的时钟(如 RCC_APB2PeriphClockCmd),否则配置无效。

📝强化题库

选择题点选即时判分;填空题输入后"检查"或"显示答案"。

已答 0/0答对 0正确率
已答 0/0答对 0