【STM32】GPIO
目录
- 1、什么是GPIO
- 2、什么是GPIO组
- 3、GPIO的基本结构
- 4、GPIO位结构
- 5、GPIO八种工作模式
- 6、GPIO相关寄存器
- 1. 端口配置低寄存器`GPIO[x]_CRL`和端口配置高寄存器`GPIO[x]_CRH`, Config Register High和Config Register Low)
- 2. 端口输入数据寄存器(GPIO[x]_IDR)
- 3. 端口输出数据寄存器`GPIO[x]_ODR`, Output Data Register
- 4. 端口位设置/清除寄存器`GPIO[x]_BSRR` Bit Set Reset Register
- 5. 端口位清除寄存器`GPIO[x]_BRR`, Bit Reset Regsiter
- 6、影子寄存器
1、什么是GPIO
GPIO(General Purpose Input/Output通用输入输出 )
通用输入输出 的缩写,是微控制器(MCU)或处理器中用于与外部设备或电路进行交互的 基本硬件接口。
如果某一个引脚支持GPIO功能, 则可以将其配置为输入或者输出.
- 数字输入:接收高电平(1)或低电平(0)信号。
- 典型如按钮输入, 将按钮连接到 GPIO 输入引脚,微控制器可以读取按钮按下或松开的状态。
- 输出模式:输出高电平(1)或低电平(0)信号。
- 典型的LED控制, 将 LED 连接到 GPIO 输出引脚,通过设置引脚的电平来控制 LED 的开关。
2、什么是GPIO组
STM32 的 GPIO 端口通常命名为 GPIOA、GPIOB、GPIOC … 依次类推,每个端口最多包含 16 个引脚,编号从 0 到 15:
- GPIOA: PA0 ~ PA15
- GPIOB: PB0 ~ PB15
- GPIOC: PC0 ~ PC15
- …
并非所有组的所有编号都可用, 需要查看手册
我的来自stm32F103VET6的原理图
3、GPIO的基本结构
4、GPIO位结构
5、GPIO八种工作模式
-
输入模式
-
输入浮空(Floating Input)
-
特点:引脚无内部上拉或下拉电阻,仅作为输入,悬空时状态不确定,容易受到干扰。
-
适用场景:需要外部电路(如 按键、传感器)来确定电平,或用于复用功能(如 USART RX)。
-
-
输入上拉(Input Pull-Up)**
- 特点:内部连接 上拉电阻,默认状态为 高电平(1),外部需要拉低才能改变状态。
- 适用场景:按键检测(常见的 低电平触发按键)。
-
输入下拉(Input Pull-Down)
- 特点:内部连接 下拉电阻,默认状态为 低电平(0),外部需要拉高才能改变状态。
- 适用场景:按键检测(常见的 高电平触发按键)。
-
模拟输入(Analog Input)
- 特点:引脚连接到 ADC(模数转换器),无数字输入特性,可接收 模拟信号。
- 适用场景:ADC(模拟传感器、电位器) 输入信号。
-
-
输出模式
-
开漏输出(Open-Drain Output)
-
特点:只能输出 低电平(0) 或 高阻态(Hi-Z),需要外部上拉电阻才能输出高电平(1)。
-
适用场景:适用于多个设备共享信号线。
- I2C 通信(总线仲裁机制需要开漏)。
- 驱动大电流外设(如 LED、继电器,上拉到 5V 或更高电压)。
-
-
推挽式输出(Push-Pull Output)
-
特点:可以直接输出 高电平(1)或低电平(0),不需要额外的上拉电阻,驱动能力强。
-
适用场景:
- 普通数字信号输出(控制 LED、继电器)。
- 高速信号输出(如 SPI、USART TX)。
-
-
-
复用模式
-
推挽式复用功能(Alternate Function Push-Pull)
- 特点 :引脚用于 外设功能(如 USART、SPI、I2C),输出方式为 推挽模式,能提供稳定的高/低电平。
- 适用场景:USART TX、SPI、PWM 输出。
-
开漏复用功能(Alternate Function Open-Drain)
- 特点:引脚用于 外设功能,输出方式为 开漏模式,通常需要 外部上拉。
- 适用场景:
- I2C(SDA、SCL) 需要 开漏 以支持多主机通信。
- 某些低功耗通信 场景。
-
模式 | 默认状态 | 是否需要外部电阻 | 主要用途 |
---|---|---|---|
输入浮空 | 悬空 | 可能需要 | 接受外部信号,无内部上拉/下拉 |
输入上拉 | 高电平(1) | 无 | 按键检测(低电平触发) |
输入下拉 | 低电平(0) | 无 | 按键检测(高电平触发) |
模拟输入 | 模拟信号 | 无 | ADC 采样 |
开漏输出 | 高阻 | 需要上拉电阻 | I2C 总线、驱动高电压负载 |
推挽输出 | 0/1 | 无 | 直接驱动 LED、继电器等 |
推挽复用 | 0/1 | 无 | SPI、USART TX、PWM |
开漏复用 | 高阻 | 需要上拉电阻 | I2C(SDA/SCL) |
6、GPIO相关寄存器
1. 端口配置低寄存器GPIO[x]_CRL
和端口配置高寄存器GPIO[x]_CRH
, Config Register High和Config Register Low)
-
bit位说明:
- 每四个bit位决定一个端口的状态
- 每个寄存器共32bit, 可以决定8个端口的状态
- 每个端口组需要两个寄存器来配置, 也就是每个端口组都有一个
CRL
和CRH
寄存器 - 寄存器为
RW
权限
-
低两位**
MODE[y]
(mode=模式)**决定输入和输出状态, 以及输出速率(速率越高, 功耗越高, 波形越不平滑)00
: 输入01
: 输出10MHz10
: 输出2MHz11
: 输出50MHz
-
高两位**
CNF[y]
(CNF=config配置)**决定具体模式- 输入模式
00
: 模拟输入01
: 输入浮空10
: 上拉下拉11
: 保留
- 输出模式
00
: 通用推挽01
: 通用开漏10
: 复用推挽11
: 复用开漏
- 输入模式
2. 端口输入数据寄存器(GPIO[x]_IDR)
- 说明:
- 每一个寄存器bit记录了一个端口的输入状态
- 每个端口组需要最多16个bit, 因此只需要
IDR
的低16bit就可以了 - 寄存器为
R
权限
bit
值为1
说明输入为高bit
值为0
说明输入为低
3. 端口输出数据寄存器GPIO[x]_ODR
, Output Data Register
- 同输入类似,
RW
权限
4. 端口位设置/清除寄存器GPIO[x]_BSRR
Bit Set Reset Register
- 同样可以实现拉高拉低输出的效果, 但是权限是
W
- 低16bit写入
1
, 会拉高某个引脚 - 高16bit写入
1
, 会拉低某个引脚 - 写入
0
, 不会影响其他引脚
5. 端口位清除寄存器GPIO[x]_BRR
, Bit Reset Regsiter
- 同
BSRR
, 权限同样是W
, 但是只能拉低 - 低16bit写入
1
, 会拉低某个引脚 - 低16bit写入
0
, 不起作用 - 高16bit不起作用
相关术语:
Set
= 将输出设置为高电平 = 拉高 = 置位 = 置为1 = 输出1 = 使能Reset
= 将输出设置为低电平 = 拉低 = 复位 = 置为0 = 输出0 = 禁用输出相关的寄存器逻辑:
正常来说,
ODR
可以直接控制某个引脚高低// 正确的操作方式, 注意操作符是 |= 和 &= GPIOA->ODR |= (1 << 5); // 拉高 PA5 GPIOA->ODR &= ~(1 << 5); // 拉低 PA5
但是对
ODR
直接操作, 可能有意无意修改到其他引脚的状态GPIOA->ODR = (1 << 5);// 此时PA5被置为1, 但是PA的其他端口被置为0
STM32于是设置了一个
BSRR
寄存器, 操作BSRR可以间接控制端口GPIOA->BSRR = (1 << 5);// 此时PA5被置为1, 其他端口不受影响 GPIOA->BSRR = (1 << (5 + 16)); // // 此时PA5被置为0, 其他端口不受影响
BSRR
对于拉高的操作比较方便 ,某组BSRR = (1 << 引脚编号);
即可, 但是拉低操作稍显复杂, 需要使用某组BSRR = (1 << (引脚编号 + 16));
来操作, 于是又设置了一个BRR, 专门用来简化拉低操作GPIOA->BSRR = (1 << 5); // 用BSRR来拉高引脚 GPIOA->BRR = (1 << 5); // 用BRR拉低引脚
6、影子寄存器
BSRR
和BRR
实际都是一种叫做影子寄存器Shadow Register
的寄存器类型影子寄存器在硬件上实际没有真正对应的寄存器, 硬件会自动将对影子寄存器的操作转换为对其他寄存器的操作, 所以大多数影子寄存器写
1
和0
都不用考虑之后其状态如何, 是否需要复位和置位等, 对影子寄存器的每次操作都是独立的, 不受前后代码影响影子寄存器通常只能写