目录
[什么是 GPIO?](#什么是 GPIO?)
[使用 SPL 操作 GPIO 的三个步骤](#使用 SPL 操作 GPIO 的三个步骤)
什么是 GPIO?
在 STM32 微控制器中,GPIO(General Purpose Input/Output,通用输入输出口) 是最基本、最常用的外设之一。它的主要作用是控制单片机引脚的电平状态,因此被广泛用于与外部设备进行交互,并且是实现各种外设功能的基础。
GPIO 引脚具备高度的可配置性,支持多种不同的工作模式,以适应不同的应用需求,主要包括以下几种:
输入模式 :将引脚配置为输入状态,用于读取外部的电平信号。例如,可以用来检测按键是否被按下,或读取来自传感器、外部模块的数字电平。
输出模式 :将引脚配置为输出状态,可以输出高电平(3.3V)或低电平(0V),以控制外部设备的工作。例如点亮或熄灭 LED,驱动蜂鸣器,或产生模拟通信的时序信号。
复用功能模式(Alternate Function) :当 GPIO 引脚不再用于普通输入/输出时,可以将其交由其他外设控制,例如作为串口(USART)、定时器(TIM)、SPI 或 I²C 接口的引脚。这种模式下,GPIO 引脚成为对应外设功能的一部分。
模拟功能模式(Analog):将引脚配置为模拟模式,可用于连接模数转换器(ADC),实现模拟信号的采集,例如电压测量、传感器模拟输出等。
综上,GPIO 是 STM32 控制和感知外部世界的桥梁,几乎参与所有的外设操作。
GPIO基本结构

左侧紫色:APB2 总线
全称:Advanced Peripheral Bus 2(高级外设总线 2)
功能:连接 CPU 和 GPIO 外设
STM32F1 系列中,GPIO 属于 APB2 总线挂载的外设,因此使用 RCC->APB2ENR 寄存器来开启它的时钟。
橙色块:GPIO 外设模块 (如 GPIOA、GPIOB)
STM32 会有多个 GPIO 端口模块,分别对应 GPIOA、GPIOB、GPIOC......等,每个端口负责 16 个引脚(Px0 ~ Px15)。
每个 GPIO 模块内部有两大部分:
- 寄存器模块
用于 CPU 配置 GPIO 的各项功能(输入/输出模式、上拉/下拉、速度、输出类型等)
常用的寄存器有:
CRL / CRH(配置模式)
IDR(输入数据)
ODR(输出数据)
BSRR / BRR(快速位操作)
LCKR(锁定配置)
CPU 通过访问这些寄存器来控制 GPIO 的工作状态。
- 驱动器模块
实际电气驱动电路,用于控制 GPIO 引脚输出高电平/低电平,或接收外部电平信号。
分为:
推挽输出:高低电平切换,能驱动电流
开漏输出:只能下拉,需外部上拉电阻
输入:读取外部状态
这些电路决定了 GPIO 的真实"电气行为"。
右侧绿色块:物理引脚
如:PA0--PA15、PB0--PB15
每个 GPIO 模块最多支持 16 个物理引脚(对应编号 0~15)
这些是在开发板上用跳线连接的实体引脚
图中流程
-
CPU 通过 APB2 总线 访问 GPIO 外设
-
配置 GPIOA / GPIOB 等模块中的寄存器
-
寄存器控制驱动器
-
驱动器作用于实际的引脚
GPIO位结构

这张图是 STM32 GPIO 引脚的硬件结构原理图,官方称为 I/O端口位的基本结构。它揭示了每个引脚(如 PA0、PB5)在硬件层面是怎么工作的。
右侧:I/O 引脚电路部分(物理接口)
I/O 引脚
图最右边的 I/O 引脚 即实际芯片上的某个引脚(如 PA13)
所有控制输入/输出行为最终都作用在这个引脚上。
上下保护二极管
两个 钳位保护二极管 分别接到 VDD 和 VSS(电源和地),用于:
防止电压过高击穿器件
限制输入电压范围(通常在 VSS - 0.3V ~ VDD + 0.3V 之间)
中间:输入/输出驱动电路
TTL肖特基触发器(上边的三角符号)
把引脚的电平转换成数字电平(高/低),传输给内部逻辑电路。
只有当 I/O 被设置为输入模式时才工作。
上下拉电阻(右边的开关电阻)
可以选择上拉到 VDD 或下拉到 VSS(由 GPIO_PUPDR 寄存器控制)
避免输入引脚悬空造成不稳定状态
输出驱动控制器(最下面的 P-MOS + N-MOS)
控制电平输出,决定是推挽输出、开漏输出还是高阻态
有一个 输出控制模块 根据寄存器配置选择不同工作模式:
推挽输出:P-MOS/N-MOS 交替导通,能输出高/低电平
开漏输出:只拉低,需外部上拉电阻拉高
关断:输出关闭,进入高阻态(常用于输入模式)
上拉(Pull-up)和下拉(Pull-down)是 GPIO 作为输入模式时的两种状态配置,用于解决外部信号未连接时的 悬空 问题:
上拉:通过内部电阻将引脚默认拉到高电平(VDD,如 3.3V)。如果外部没有输入信号(引脚悬空),引脚会稳定在高电平;当外部输入低电平时,引脚被拉低。
下拉:通过内部电阻将引脚默认拉到低电平(GND,0V)。如果外部没有输入信号,引脚会稳定在低电平;当外部输入高电平时,引脚被拉高。
推挽(Push-Pull)描述的是输出电路的工作方式,由两个互补的晶体管(或 MOS 管)组成:当输出高电平时,上方的晶体管导通(推 电流流出引脚,提供高电平)
当输出低电平时,下方的晶体管导通(拉 电流流入引脚,接地形成低电平)
这种结构能主动输出高电平和低电平,驱动能力强(可提供较大电流),因此叫推挽------ 像两个人一推一拉,能稳定输出两种电平。
开漏(Open-Drain)中的 漏 指 MOS 管的漏极(Drain)。输出电路仅包含一个漏极接引脚的 MOS 管,源极接地:当输出低电平时,MOS 管导通,引脚通过管子接地(输出 0V)
当输出高电平时,MOS 管截止,引脚与内部电路断开(开漏 状态),此时引脚电压由外部上拉电阻决定(通常接 VDD,输出 3.3V)
只能下拉 是指:内部电路只能主动将引脚拉到低电平,高电平无法主动输出,必须依赖外部电阻 拉上去。
左侧:数据控制逻辑(寄存器区)
输入数据寄存器(IDR)
连接输入触发器,读取引脚电平状态
输出数据寄存器(ODR)
控制引脚输出电平
输出控制逻辑
从 MCU 内部总线接收指令,通过 多路复用器(MUX)选择复用输出或 GPIO 输出
置位/清除寄存器(BSRR/BRR)
快速设置/清除某个引脚的高低电平,避免读改写出错
BSRR(双向寄存器):
高 16 位:写 1 时清除对应引脚(例如第 16 位写 1 → 引脚 0 输出 0);
低 16 位:写 1 时置位对应引脚(例如第 0 位写 1 → 引脚 0 输出 1);
写 0 时无操作,因此可通过一条指令同时控制多个引脚 。
置位就是变为1,清除就是变为0
复用与模拟输入
图中还包括了 复用功能输入/输出 路径(如串口、定时器等)
模拟输入 是指 ADC 使用该引脚时,跳过数字电路,直接连接到模数转换模块
回顾这张图,只需要知道以下几点即可:
每个 GPIO 引脚都可以是输入或输出,背后都有电路支持
上拉/下拉电阻用于稳定输入状态,防止悬空
输出模式分推挽和开漏,有不同电路行为
所有操作都是靠访问寄存器来控制这些开关电路
GPIO 也可以被外设复用(UART、ADC、PWM)
GPIO模式
通过配置 GPIO 的端口配置寄存器,端口可以配置成以下8种模式

使用 SPL 操作 GPIO 的三个步骤
第一步:开启 GPIO 时钟
cpp
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
第一个参数表示哪个外设(GPIOA、USART1...)
第二个参数 ENABLE / DISABLE 表示是否开启
第二步:配置 GPIO 模式
cpp
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
使用 GPIO_Init() 对引脚进行一次性配置
第三步:读/写 GPIO 电平
cpp
GPIO_SetBits(GPIOA, GPIO_Pin_0); // PA0 输出高电平
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // PA0 输出低电平
// 或读取
uint8_t state = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
硬件电路
高电平点亮型电路(LED 阳极接 3.3V)

PA0 输出低电平点亮 LED
低电平接地型电路(LED 阴极接 GND)

PA0 输出高电平点亮 LED
PNP 型三极管(S8550)驱动电路

电路结构:
使用的是 PNP 型三极管(S8550)
三极管的 发射极接 3.3V
负载(如蜂鸣器)接在集电极与地之间
PA0 通过 R1 控制基极(电流限流)
PA0 输出低电平时,三极管导通,负载工作。
NPN 型三极管(S8050)驱动电路

电路结构:
使用的是 NPN 型三极管(S8050)
三极管的 发射极接地
负载(如蜂鸣器)接在 3.3V 与集电极之间
PA0 通过 R1 控制基极
PA0 输出高电平时,三极管导通,负载工作。
传感器信号采集模块电路原理图

LM393 比较器部分(左侧)
元器件:
U1: LM393 双路电压比较器
C1: 去耦电容,用于电源滤波
功能:
将输入信号(IN+ 与 IN-)进行比较
如果 IN+ > IN-,输出 高电平
如果 IN+ < IN-,输出 低电平
输出引脚为 DO(Digital Output)
电压比较输入部分(中左)
元件说明:
R2: 设定阈值的电位器或分压电阻,接到 IN-
N1: 传感器元件(如光敏电阻、热敏电阻、红外管)
R1: 上拉电阻,用于与传感器组成电压分压回路
IN+: 来自分压点的模拟电压
工作原理:
N1(传感器)电阻随外部物理量(光、热、红外)变化
与 R1 构成分压,形成 IN+ 电压信号
与设定好的 IN- 电压进行比较
比较器根据高低判断输出 DO(0/1)
模拟信号输出(AO)
AO 是从 R1 与 N1 的中点直接引出的 分压电压
它表示当前传感器输出的连续电压值
可以接 STM32 的 ADC 引脚读取
尚未完结