GPIO 外设

GPIO 外设

1. 什么是 GPIO

General-purpose and alternate-function I/Os (GPIOs and AFIOs)GPIO 是微控制器(如 STM32)与外界交互的核心接口,通过配置引脚模式实现灵活控制,即用程序来控制或读取 GPIO 引脚的输入或输出。AFIO 是 STM32 微控制器中用于管理 GPIO 引脚复用功能的关键模块,其核心作用是将物理引脚动态配置为外设功能(如 USART,SPI,PWM 等),而非仅作为普通输入 / 输出。即复用 IO 引脚来控制外设。

​ 可由 STM32 直接驱动 GPIO 引脚从而实现与外部设备通信,控制以及采集和捕获的功能。

1.1 GPIO 详情

​ STM32 有多组 GPIO,不同的 STM32 芯片有不同组的 GPIO 端口。以 STM32F103ZET6 为例,其共有 7 组 GPIO 端口,分别是 GPIOx(x 从 A-G),每组控制 16 个引脚,共有 112 个 GPIO 引脚。可通过查询对应的 STM32 芯片的数据手册,来获取对应的信息。

​ 每个引脚的电平是 0-3.3V,部分引脚最高可以兼容到 5V。

image-20250402164734410

1.2 GPIO 的主要特点

​ (1)不同型号,IO 口的数量可能不一样。

​ (2)快速翻转。最快可以达到每 2 个时钟周期翻转一次。(STM32F1 系列最快可以达到 50MHz 的翻转速度)。

​ (3)每个 IO 都可以作为外部中断。

​ (4)支持 8 种工作模式。

2. GPIO 工作模式

2.1 GPIO 每位的具体电路结构

​ 每个通用输入 / 输出端口都有两个 32 位的配置寄存器(GPIOx_CRL, GPIOx_CRH)、两个 32 位的数据寄存器(GPIOx_IDR, GPIOx_ODR)、一个 32 位的置位 / 复位寄存器(GPIOx_BSRR)、一个 16 位的复位寄存器(GPIOx_BRR)和一个 32 位的锁定寄存器(GPIOx_LCKR)。

image-20250402163325196

image-20250402163455174

2.2 GPIO 的八种工作模式

​ GPIO 端口的每个位(引脚)可以由软件分别配置成 8 种模式,当然对同一个引脚同一时间只能处于某一种模式中。

模式名称 功能类型 模式介绍
输入浮空(Input floating) 数字输入 浮空输入状态下,IO 的点评状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平时不确定的
上拉输入(Input pull-up) 数字输入 IO 口在无输入的情况下,保持高电平
下拉输入(Input-pull-down) 数字输入 IO 口在五输入的情况下,保持低电平
模拟输入(Analog) 模拟输入 输入信号不经施密特触发器直接接入,输入信号为模拟量而非数字量,其余输入方式输入数字量
通用开漏输出(Output open-drain) 数字输出 只能输出低电平
通用推挽式输出(Output push-pull) 数字输出 可以输出高低电平
推挽式复用功能(Alternate function push-pull) 数字输出 此时 IO 受内部外设控制,比如定时器的 PWM,比如 SPI 的 MOSI,MISO 等。而普通的推挽输出,则受 ODR 控制
开漏复用功能(Alternate function open-drain) 数字输出 参考复用推挽

​ 每个 I/O 端口位可以自由编程,然而 I/O 端口寄存器必须按 32 位字被访问。

​ 输出模式下可以控制端口输出高电平低电平,用于驱动 LED,蜂鸣器等,如果是大功率器件(比如电机),还需要加上驱动器(小电流控制大电流)。

​ 输入模式下可以读取端口的高低电平,用于读取外接按键,外接模拟信号的输入,ADC 电压采集,模拟通信协议接受数据等。

2.2.1 输入配置

image-20250402170645911

当 I/O 端口被编程为输入模式时:

  • 输出缓冲区被禁用
  • 施密特触发器输入被激活
  • 弱上拉和下拉电阻器根据输入配置(上拉、下拉或浮空)被激活或不激活:
  • 每个 APB2 时钟周期,I/O 引脚上的数据被采样到输入数据寄存器中
  • 对输入数据寄存器的读取访问获取 I/O 状态。

2.2.2 模拟配置

image-20250402172910116

当 I/O 端口编程为模拟配置时:

  • 输出缓冲区被禁用。
  • 施密特触发器输入被停用,为每个 I/O 引脚的模拟值提供零消耗。施密特触发器的输出被强制设定为一个恒定值(0)。
  • 弱上拉和下拉电阻被禁用。
  • 对输入数据寄存器的读取访问得到值 “0”。

2.2.3 输出配置

image-20250402171310143

当 I/O 端口被编程为输出模式时:

  • 输出缓冲区已启用
    • 开漏模式:输出寄存器中的 “0” 激活 N-MOS,而输出寄存器中的 “1” 使端口处于高阻态(P-MOS 永远不会激活)
    • 推挽模式:输出寄存器中的 “0” 激活 N-MOS,而输出寄存器中的 “1” 激活 P-MOS
  • 施密特触发输入被激活。
  • 弱上拉和下拉电阻被禁用。
  • 每个 APB2 时钟周期,I/O 引脚上的数据被采样到输入数据寄存器中
  • 对输入数据寄存器的读取访问获取开漏模式下的 I/O 状态
  • 对输出数据寄存器的读取访问获取推挽模式下最后写入的值

2.2.4 复用功能配置

image-20250402174038789

当 I/O 端口被编程为备用功能时:

  • 输出缓冲区以开漏或推挽配置打开
  • 输出缓冲区由来自外设(备用功能输出)的信号驱动
  • 施密特触发输入被激活
  • 弱上拉和下拉电阻被禁用
  • I/O 引脚上的数据每 APB2 时钟周期采样到输入数据寄存器中
  • 对输入数据寄存器的读取访问获取开漏模式下的 I/O 状态
  • 对输出数据寄存器的读取访问获取推挽模式下最后写入的值

3. GPIO 寄存器

每个 GPIO 端口有 7 个相关的寄存器:

  • 2 个 32 位配置寄存器(GPIOx_CRL,GPIOx_CRH)。
  • 2 个 32 位数据寄存器(GPIOx_IDR,GPIOx_ODR)。
  • 1 个 32 位置位 / 复位寄存器(GPIOx_BSRR)。
  • 1 个 16 位复位寄存器(GPIOx_BRR)。
  • 1 个 32 位锁定寄存器(GPIOx_LCKR)。

3.1 GPIOx_CRL(端口配置低寄存器)

Port configuration register low (GPIOx_CRL) (x=A..G)

image-20250402174823039

该寄存器配置的每个 GPIO 的 0-7 这个 8 个位,所以叫低寄存器。

CNFy [1:0]:端口 x 配置位

这些位由软件写入以配置相应的 I/O 端口。

详情请参阅 3.3 端口位配置表。

  • 在输入模式(MODE [1:0]=00):

    • 00:模拟模式

    • 01:浮空输入(复位状态)

    • 10:带上拉 / 下拉的输入

    • 11:保留

  • 在输出模式(MODE [1:0] > 00):

    • 00:通用输出推挽

    • 01:通用输出开漏

    • 10:备用功能输出推挽

    • 11:备用功能输出开漏

3.2 GPIOx_CRH(端口配置高寄存器)

Port configuration register high (GPIOx_CRH) (x=A..G)

image-20250402175037267

该寄存器配置的每个 GPIO 的 8-15 这个 8 个位,所以叫高寄存器。

配置方式和低位寄存器完全一样。

3.3 端口位配置表

image-20250402175409086

3.4 GPIOx_IDR(端口输入数据寄存器)

Port input data register (GPIOx_IDR) (x=A..G)

image-20250402180539693

Bits 31:16 保留,必须保持在复位值。

Bits 15:0 IDRy:端口输入数据(y= 0 .. 15)

这些位是只读的,并且只能在字模式下访问。它们包含相应 I/O 端口的输入值。

保留位始终读为 0。剩下的分别对应每个引脚的输入值。

3.5 GPIOx_ODR(端口输出数据寄存器)

Port output data register (GPIOx_ODR) (x=A..G)

image-20250402181008644

Bits 31:16 保留,必须保持在复位值。

Bits 15:0 ODRy:端口输出数据(y= 0 .. 15)

这些位可以通过软件读写,并且只能以 Word 模式访问。

注意:对于原子位的置位 / 复位,可以通过向 GPIOx_BSRR 寄存器(x = A .. G)写入来单独设置和清除 ODR 位。

保留位始终读为 0。剩下的分别对应每个引脚的输出值。

3.6 GPIOx_BSRR(端口位设置 / 清除寄存器)

Port bit set/reset register (GPIOx_BSRR) (x=A..G)

image-20250402181303526

Bits 31:16 BRy: 端口 x 复位位 y (y= 0 .. 15)

  • 这些位是只写位,只能在字模式下访问。

  • 0: 对应的 ODRx 位无操作

  • 1: 复位对应的 ODRx 位

Bits 15:0 BSy: 端口 x 设置位 y (y= 0 .. 15)

  • 这些位是只写位,只能在字模式下访问。
  • 0: 对应的 ODRx 位无操作
  • 1: 设置对应的 ODRx 位

注意:如果 BSx 和 BRx 同时设置,BSx 优先。

高 16 位是用清除对应的数据输出寄存器的位(0-15)的值:设置为 0 不影响,设置为 1 会清除 ODR 对应的位的值(置为 0)。

低 16 位是用设置对应的数据输出寄存器的位(0-15)的值:设置为 0 不影响,设置为 1 会设置 ODR 对应的位的值(置为 1)。

3.7 GPIOx_BRR(端口位清除寄存器)

Port bit reset register (GPIOx_BRR) (x=A..G)

image-20250402182138895

Bits 31:16 保留

Bits 15:0 BRy: 端口 x 复位位 y (y= 0 .. 15)

这些位是只写位,只能在字模式下访问。

  • 0: 对应的 ODRx 位无操作
  • 1: 复位对应的 ODRx 位

这个寄存器具有了 GPIOx_BSRR 一半的功能:清除。

3.8 GPIOx_LCKR(端口配置锁定寄存器)

Port configuration lock register (GPIOx_LCKR) (x=A..G)

该寄存器用来锁定端口位的配置。位 [15:0] 用于锁定 GPIO 端口的配置。在规定的写入操作期间,不能改变 LCKR [15:0]。当对相应的端口位执行了 LOCK 序列后,在下次系统复位之前将不能再更改端口位的配置。

每个锁定位冻结了控制寄存器(CRL, CRH)相应的 4 位(CNF2 位和 MODE2 位)。

image-20250402182600168

Bit 16 用来激活锁定寄存器,必须按照规定的时序来操作才行:写 1-> 写 0 -> 写 1 -> 读 0 -> 读 1。

Bits 15:0 LCKy: 端口 x 锁定位 y(y= 0 .. 15)

这些位是可读写的,但只有当 LCKK 位为 0 时才能写入。

  • 0: 端口配置未锁定。
  • 1: 端口配置已锁定。