嵌入式:深刻理解GPIO的通用/复用推挽输出、开漏输出

前言

文章以STM32F103ZET6芯片为例来介绍

一、宏观认识

1. GPIO是什么

GPIOGeneral Purpose Input/Output 的简写,字面含义就是 "通用输入 / 输出"

是一个 MCU 内部,用来做输入输出控制器电路


2. GPIO在哪里

GPIO属于MCU中的一个片上外设!!


3. 理解GPIO输入输出

  • 输入输出的是什么?
    本质就是输入输出高低电平。

**为什么要输出?**这些高低电平,在上层语言层解释就是 0/1,在下层硬件外设角度,就会被视为 MCU 控制外设的手段,比如,输出高电平,会被 LED 解释为要求点亮 LED,会被电机解释成为电机正转,会被串口接收方解释为传送 1 等等,输出低电平,则反之。

**为什么要输入?**单片机的核心作用是 "控制 ",控制相关外设,就必须先获取外设相关的数据,比如需要知道开关是否被闭合,传感器是否感受到数据变化,设备是否处于休眠等,然后根据外设状态数据变化,在通过输出,控制外设或者报告给用户等。

所以:输入输出的本质是输入输出高低电平 (手段),达到获取外设信息,控制外设的目的。


4. 理解GPIO通用

  • 为什么叫做通用输入输出?
    "通用",意思就是一个东西被发明出来,就是未来给 "大家" 用的。

英语被发明出来,英国人可以用,美国人可以用,我们中国人也可以用,所以,英语叫做世界 "通用" 语言。

同样的道理,GPIO 是通用输入输出,GPIO 自己可以输入输出高低电平,未来 MCU 内集成了其他外设控制器,而其他外设控制器,也要输出高低电平,来控制外设怎么办?

难道给每一个外设控制器也焊接输入输出高低电平的硬件电路吗?这样做势必会增加复杂度,这样无疑会隐形的增加单片机成本,包括功耗。

所以,GPIO 都已经做了输入输出高低电平了,其他外设控制器你就别凑热闹了,直接用 GPIO 不就好了。所以, GPIO 叫做通用输入输出。
✨"通用",意思就是一个东西被发明出来,就是未来给 "大家" 用的。这里的大家,就是集成在 MCU 中的各种外设控制器或者与用来控制外设的硬件电路。
✨ 我们把其他外设控制器,直接使用 GPIO 硬件电路来进行输入输出的方式,叫做复用 GPIO

5. MCU内部的GPIO

名词说明:

  • **Pin:**就是引脚的意思

  • Port:端口的意思,PORT 原意为 "港口",在计算机科学中引申为 "数据交换的入口或出口",现代微控制器(如 STM32)继承了这一概念,将一组 GPIO 引脚称为 "GPIO PORT"(如 GPIOA、GPIOB),因为它们本质上是芯片与外部世界的 "数据交换接口"。

  • 为什么不叫 GPIO Group,而叫做 GPIO Port ?Group 只能体现分组概念,体现不出来数据交换的概念。Port 在计算机领域,就有数据交换的概念成分。


细节:

  1. 所有的 GPIO 控制器,都是挂接在 APB2 桥设备上的
  2. 为了管理一个一个的 pin (引脚),MCU 把 pin 划分成为了组,叫做 GPIO Port,STM32F103ZET6 一共 7 组,分别是 GPIOA~GPIOG
  3. 每一个 GPIOX (X 范围 A‑G ),都管理 0,15 个 Pin
  4. MCU 管理 GPIO Pin 的方式,是层状的,多叉树型结构

二、IO端口位电路结构

注意:

GPIO 端口位是指 GPIO 端口中单个引脚的控制单元,例如 PA0、PB3 等

每一个 Pin 对应到 MCU 内部,都会存在一套这样的硬件结构

每一个 Pin,都可以独立的进行输入和输出 换句话说

所以,我们搞清楚了一个 Pin 是如何输入输出的,那么其他 Pin 也就会了

1. IO输入路径理解

简化理解:

2. IO输出路径理解

简化输出理解:

✨结论:

  1. 片上外设,其实是 MCU 内部的各种外设控制器,或者控制电路

  2. 宏观上,一定要时刻记着,MCU != CPU,MCU 内部是包含了片上外设控制器 + ARM‑CPU 的

  3. GPIO 被设计出来,不是只让 ARM‑CPU 进行 IO 读写数据的,而是让所有片上设备进行 IO 的,这就是为什么 STM32 芯片引脚中,大部分引脚都是 GPIO Pin 的原因,也是我们学习单片机,需要优先学习 GPIO 的原因,因为他为所有片上外设提供 IO 能力

  4. 未来我们学习的其他片上外设,不用单独设计 IO 接口电路,直接复用 GPIO 即可,这样可以大大减少 MCU 内部硬件电路设计的复杂度,减少功耗,最终表现在单片机价格上,价格便宜了,应用场景就会更丰富,因为各种智能场景用得起 (当然这只是原因之一,重点在感受生态问题上)。

三、IO端口保护

端口钳位保护

双二极管钳位电路

  • 二极管导通压降一般在 0 点几伏 (常见的基本都在 0.6~0.7V 左右)

为了说明该问题,我们假设如下数值:

Vdd = 3.3V,Vss = 0V,二极管导通电压是 0.7V(二极管是一个元器件,自身也存在电阻,自身会承压)

结论:

  • 当 输入电压 >=(Vdd + 保护二极管导通压降)时,上路二极管导通,这时被钳位在 Vdd + 二极管导通压降

  • 当 输入电压 <=(Vss‑保护二极管导通压降)时,下路二极管导通,这时被钳位在 Vss‑二极管导通压降

✨思考:

  • 上面的数值具体是多少不重要,**重要的是,**因为有了钳形保护二极管,就可以有效防止不合理电压输入到针脚,进而形成大电流,导致击穿 MCU 内部元器件,本质是一种保护电路!

四、GPIO 工作模式

GPIO 主要负责 MCU 的输入和输出,也就是 I/O 问题,GPIO 的输入、输出拥有多种工作模式:

输出模式

  1. 通用推挽输出
  2. 通用开漏输出
  3. 复用推挽输出
  4. 复用开漏输出

输入模式

  1. 浮空输入
  2. 上拉输入
  3. 下拉输入
  4. 模拟输入

先暂时不论这些模式具体含义,后面会逐一讲解,先从宏观层面理解。
✨为什么 GPIO 会有这么多 I‑O 模式?

  1. GPIO 不止能够由 ARM‑CPU 直接控制输入输出,还可供其余片上外设调用,GPIO 属于共用资源。
  2. 片上外设种类繁多、使用场景各不相同,因此 GPIO 需要丰富的 I/O 功能适配各类外设。
  3. 类比键盘:只打游戏只需要 WASD 按键;但是键盘还要用于打字、聊天,因此按键数量很多,适配全部场景。
    总结:GPIO 具备多种 I/O 模式,目的是满足各类片上外设、不同使用环境下的引脚需求

五、输出部分电路

1. 输出部分电路

输出模式下,需要研究 GPIO 端口内部的输出硬件单元。

输出部分包含:输出数据寄存器、复用功能输出选择、输出驱动器、P‑MOS、N‑MOS 管,最外侧为双向保护二极管。

2. 四种输出模式

输出一共四种模式:

  • 通用推挽输出
  • 通用开漏输出
  • 复用推挽输出
  • 复用开漏输出
推挽 开漏
通用 通用推挽输出 通用开漏输出
复用 复用推挽输出 复用开漏输出
  • 通用:由 ARM‑CPU 直接操控 GPIO 引脚输出电平。
  • 复用:MCU 内部片上外设接管 GPIO 引脚,外设利用引脚完成输入输出。

3. 理解输出电路

3.1 简化输出电路图

输出寄存器为多位,这里简化成单比特方便理解。
复用器

  • 作用:在多路输入信号当中选出一路作为有效输出信号。
  • 用途:决定引脚控制权归属,是 CPU 直接控制,或是交给片上外设。

输出控制

接收控制电平,驱动后端 MOS 管的栅极,管控 MOS 管通断,转换成具备驱动能力的引脚电平。

3.2 P‑MOS 和 N‑MOS

名词释义

  1. MOS:Metal‑Oxide‑Semiconductor Field‑Effect Transistor(金属氧化物半导体场效应管),简写 MOSFET,再简写:MOS,这个不用记
  2. P‑MOS:P‑channel Metal‑Oxide‑Semiconductor(P 沟道金属氧化物半导体),这个不用记
  3. N‑MOS:N‑channel Metal‑Oxide‑Semiconductor(N 沟道金属氧化物半导体),这个不用记
  4. P:positive,积极的,正向的
  5. N:negative,消极的,负面的,反向的

**P‑MOS 和 N‑MOS 是本质是:**本质是一个开关。
MOS 引脚定

  • **S:**source,源极,"Source" 意为 "源头",指这里是载流子(电子或空穴)的来源
  • **D:**Drain,漏极,"Drain" 意为 "漏出",指载流子最终从这里流出器件,D 当做 Destination 看貌似也行,但是 Destination 是目的地的意思,MOS 管往往不是目的地,而是一个电流路过的器件,所以官方 Drain 更好一些。
  • **G:**Gate,栅极,Gate 就是门的意思,预示着开关的开启和关闭由它控制

导通特性

  • P‑MOS:电流方向 S → D
  • N‑MOS:电流方向 D → S
  • P‑MOS 适合传输高电平;N‑MOS 适合传输低电平。
  • 栅极电平改变开关的开启、关闭。
  • 被控制电流方向从 Source 流向 Drain,就是 P‑型 MOS 管
  • 被控制电流方向从 Drain 流向 Source,就是 N‑型 MOS 管
  • positive,积极的,正向的,所以符合 S‑>D,顺势而为
  • negative,消极的,负面的,反向的,所以符合 D‑>S,逆行行舟
  • 但是,无论是从 S‑>D,还是从 D‑>S,电路必须是导通的,上面的图,默认都是没有导通的

那么对于 P‑MOS 和 N‑MOS 管,如何导通呢?给 G 极施加一个小电流,就可以导通。

P‑MOS 导通过程
  • **施加电压的过程,就是一个闭合开关的过程,**施加力的方向,和红色箭头方向一致,这个就是 positive,积极的,正向的,也是顺势而为的,所以叫做 P‑MOS 管。
N‑MOS 导通过程
  • **施加电压的过程,就是一个闭合开关的过程,**施加力的方向,和红色箭头方向相反,与之对抗,这个就是 negative,消极的,负面的,反向的,对抗趋势,逆流而上,所以叫做 N‑MOS 管。
    ✨结论:

  • P‑MOS 和 N‑MOS 的本质是什么?
    是一个开关

  • 为什么要有 P‑MOS 和 N‑MOS?
    通过小电压,通过控制开关的手段,达到控制大电流的目的

✨注意:

  • GPIO 输出电路图中,上方是 P‑MOS,下方是 N‑MOS

  • 两者 D 极相接,P‑MOS S 极接 VDD (3.3V),N‑MOS S 极接地 (GND)

3.3 再次简化输出电路图


六、通用推挽输出(Push‑Pull Output)

**核心思想:**交替闭合或者开启 P‑MOS 和 N‑MOS
前期基础知识点

  1. P‑MOS 和 N‑MOS 的本质是什么?
    是一个开关
  2. 为什么要有 P‑MOS 和 N‑MOS?
    通过小电压,通过控制开关的手段,达到控制大电流的目的

注意:

  • GPIO 输出电路图中,上方是 P‑MOS , 下方是 N‑MOS
  • 两者 D 极相接, P‑MOS S 极接 VDD (3.3V), N‑MOS S 极接地 ( GND , 当成 0V 就可以)

1. 输出高电平

输出数据寄存器写 1,闭合 P‑MOS,断开 N‑MOS,输出高电平

2. 输出低电平

输出数据寄存器写 0,断开 P‑MOS,闭合 N‑MOS,输出低电平

通用推挽输出的名称来源于该电路的工作原理

  1. 使用一对互补的晶体管(通常是 CMOS 工艺的 P‑MOS 和 N‑MOS 管)来输出高电平 (提供电流,"推") 或 输出低电平**(吸收 / 拉取电流,"挽")。**
  2. 本质是交替闭合断开,P‑MOS 和 N‑MOS 开关,让外部引脚接入 VDD 或者接地,进而对外呈现出高电压和低电压,然后因为电路通路,形成有输出电流 (推) 和吸收 (挽) 电流的效果

如果 P‑MOS 和 N‑MOS 都导通会是怎么的情况呢?

注意:

  • VDD 就会和 GND (Vss) 接通,这就会导致短路烧毁电路
  • 因此 "输出控制" 单元必须保证 2 个 MOS 管不能同时导通

3. 推挽输出过程

  1. 当 ARM‑CPU 执行用户的代码,用户代码要求向数据寄存器写入 1
  2. ARM‑CPU 执行用户代码,向数据寄存器写入 1
  3. 复用器选择信号输入源是数据寄存器
  4. 输出控制器获取到数字 1,把数字 1 进行解释,给 P‑MOS 管施加电压,N‑MOS 什么都不做
  5. P‑MOS 感受到电压,导通
  6. 外部引脚接入 VDD,对外输出高电平
  7. 写 0 同上

4. MOS 管导通条件(了解)

到这里,我们已经理解了推挽输出,P‑MOS 和 N‑MOS 的作用和基本原理,但是仍旧有一个问题,那就是 G 栅极电压给多大,就能开启开关。这里需要引入新的名词

  • 对任意 MOS 管而言 (P‑MOS/N‑MOS), MOS 管导通需要的电压阈值我们定义为 Vth,Voltage Threshold,也叫做阈值电压这个电压一般范围是 0.3V~1.0V
  • 源极电压定义为 Vs,栅极电压定义为 Vg
  • 对任意 MOS 管而言 (P‑MOS/N‑MOS), **导通条件:**取决于 S 源极和 G 栅极的电压差,是否超过 Vth,和 D 漏极无关
  • 对于 P‑MOS 而言,当 Vs‑Vg>Vth 时,MOS 管 SD 导通(饱和),否则 SD 断开(截止)
  • 对于 N‑MOS 而言,当 Vg‑Vs>Vth 时,MOS 管 SD 导通(饱和),否则 SD 断开(截止)
  • 对于 MOS 而言,开关速度非常高,达到 ns 级

推导出如下结论:

  • 对于 P‑MOS,Vs − Vg 电压差超过 Vth,就导通
  • 对于 N‑MOS,Vg − Vs 电压差超过 Vth,就导通

5. 最终总结

  • 推挽模式下,向输出寄存器写 1/0 的本质:是让输出控制器选择 P‑MOS,还是 N‑MOS,进而输出电压,打开指定 MOS 管。

简易原理概括

  1. P‑MOS:源极接电源 VDD;栅‑源压差达标之后导通,向引脚推出电流、输出高电平
  2. N‑MOS:源极接 GND;栅‑源压差达标之后导通,把引脚电流拉入地、输出低电平
  3. 硬件互锁保证两只 MOS 不会同时导通,规避电源对地短路。

七、通用开漏输出 (Open‑Drain Output)

✨ 开漏输出核心思想: 去掉 P‑MOS,让 P‑MOS 永远都关闭

所以,开漏模式下,我们只考虑

所以,在开漏模式下,MCU 针对特定引脚的输出,都是该引脚对应的 N‑MOS 的漏极输出

✨ 结论:

  • 向输出数据寄存器写 1 ,最终表示的是 N‑MOS 断开
  • 向输出数据寄存器写 0 ,表示 N‑MOS 管闭合

1. 输出低电平

输出数据寄存器写 0 ,N‑MOS 闭合,输出低电平

2. 输出高阻抗

输出数据寄存器写 1 ,N‑MOS 断开,输出高阻态

✨ 所谓高阻抗,只是一种说法,理解为: MCU 和外部针脚彻底断开,相当于开路了,或者 N‑MOS D 漏极和外部引脚互相悬空了

对于针脚而言,如果内部 MCU 断开了和外部引脚的连接,可以把 MCU 认为成为一个阻值无穷大的设备,我们把这种情况,叫做输出高阻抗。

✨ 结论:

  • 开漏模式,输出只能输出低电平和高阻抗,无法输出高电平

3. 开漏模式输出高电平

通过以上原理分析,可以知道:开漏输出电路有输出低电平和开路(高阻)2 个状态。

那如何才能输出高电平呢?

**通过上拉电阻将 I/O 口接通到上拉的电压。**因为 MCU 内部电路已经设计好,所以往往这个所谓的上拉的电压,必须是开发板设计者,在 MCU 外部,根据自己的需求设计的。

注意:

  • 单片机内部,不是只有 MCU 内部有 VDD 供电,其他 MCU 外部的设备,或者 MCU 内部的其他设备,也可能会有自己的供电电源提供高电压。

  • 这就好比,你家 (单片机) 里有很多家用电器 (外设控制器和外设),不止电视要供电,冰箱洗衣机也要的

那么,在开漏模式下,要输出高电平,就必须在引脚位置设置上拉电阻,来提供高电压了。

新增上拉电阻之后:

  • 输出数据寄存器写 0,N‑MOS 闭合,输低电平,图略
  • 输出数据寄存器写 1,N‑MOS 断开,输出高阻抗,外部引脚在外部上拉电阻的影响 (或者上拉) 下,输出高电平

4. 为什么开漏输出高阻抗之后,引脚就是高电平?

为了方便解释,为上图中的相关电阻进行命名:

  • 上拉电阻的阻值是 R_PULL
  • 引脚阻值是 R1,其实引脚就是导线,这个 R1 是无限趋近于 0Ω 的,后续我们不需要研究它,这里进行命名只是为了表示方便
  • 开路位置电阻命名为 R2 , 阻值无穷大

是时候,引入我们高中学过的知识了,欧姆定律: V = I * R。 因为整个电路通路,从 VDD 到 GND

  • 整个电路的电流 I = 3.3V / (R_PULL+ R1 + R2) , 因为 R2 接近于无穷大,所以 I ≈ 0
  • 而引脚位置的电压 V 引脚 = 3.3V − 上拉电阻处的承压 = 3.3V − I * R_PULL
  • 因为 I≈0,所以 V 引脚 = 3.3V − I * R_PULL = 3.3V − 0 * R_PULL = 3.3V
  • 所以,引脚处电压就是 3.3V,那么输出就是高电平

**OK啊,所以我们现在回答了为什么开漏输出高阻抗之后,引脚就是高电平,**可是上面的推断我们真的理解了吗?当然,也不知道具体哪里不清楚,反正就是感觉不透彻。

那么,接下来让我提出并解决一些问题,看看能不能透彻的理解。我们把视角转到这张图:

✨ 奇怪的问题?

真实情况是开路了,开路就没有电流啊,即电流 I=0,根据欧姆定律, V = I * R,那么整个电路结构中,都没有电压,包括引脚处,这点很明显和上面的结论是冲突的啊?
问题出在哪里呢?

一块裸的电池,没有接入到任何电路中,其实就是自身开路,正极有电压吗?

答案是当然有!

  • 电压的本质是两端 (正负等) 电势差,开路情况也可能存在

  • 就好像水龙头,不打开,也有水压一样

  • 其实,开漏输出下,高阻抗输出,对应的开路下,引脚处是有电压的。上述问题其实是出在对于欧姆定律的理解有偏差上

  • 欧姆定律可以用来计算整个电路回路的电流, 但是,计算的电压,并不是电路中某个设备 (电阻) 处的电压绝对值,而是这个设备在整个电路中承担的电压差!!

有了上面对欧姆定律的深刻理解,然后我们再回过头看这张图:

**我们就能理解为什么引脚 (就是导线) 处的电压:**V 引脚 = 3.3V − I * R_PULL = 3.3V − 0 * R_PULL = 3.3V

5. 为什么要上拉电阻

开漏输出不仅仅要考虑 N‑MOS 断开输出高阻抗的问题,电路设计上,还要考虑 N‑MOS 闭合接地的情况

如果没有上拉电阻

设置上拉电阻

6. 为什么叫上拉电阻

⭐ 在开漏输出模式并且有外部上拉电阻的情况下:

  • 如果 N‑MOS 管断开,MCU 输出高阻抗,那么引脚输出的就是外部上拉电压 3.3V,输出高电平

  • 如果 N‑MOS 管闭合,外部引脚接地,输出低电平

  • 在开漏模式,MCU 默认只能输出低电平和高阻抗

  • 所以外部接入电阻 + 高电压,在保证电路安全的情况下,就可以成功让开漏模式输出高低电平了,而输出高电平,是被外部电阻 + 高电压拉起来的,我们把这个电阻就叫做上拉电阻。

  • 上拉电阻的阻值一般多少合适? 4.7kΩ~10kΩ,这个不做解释

八、复用推挽输出

理解了通用推挽输出,复用推挽输出自然也就懂了,只不过是从CPU的输出,变成了其他片上外设的输出。

九、复用开漏输出

理解了通用开漏输出,复用开漏输出自然也就懂了,只不过是从CPU的输出,变成了其他片上外设的输出。

相关推荐
zcmodeltech2 小时前
智慧城市沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的园区-城市-数字孪生联动方案
服务器·数据库·人工智能·stm32·嵌入式硬件·信息可视化·智慧城市
Run_Teenage2 小时前
嵌入式:认识STM32命名方法和引脚定义,认识仿真器
stm32·单片机·嵌入式硬件
lhbweilai2 小时前
STM32 时钟源&时钟树(hal库)
stm32·单片机·嵌入式硬件
lhbweilai15 小时前
STM32 ADC模拟数字转换(hal库)
stm32·单片机·嵌入式硬件
坏柠15 小时前
通信协议入门:单片机怎样把一个数字发送出去?
单片机·嵌入式硬件
小僧景贤16 小时前
STM32 工程文件深度解析(Keil‑MDK + STM32CubeIDE)
stm32·单片机·stm32cubeide
国科安芯17 小时前
低轨卫星姿态与轨道控制系统中高可靠MCU的选型研究——基于AS32S601的抗辐照性能试验数据分析
分布式·科技·单片机·嵌入式硬件·系统架构
小羊先生car18 小时前
RTOS-F429-HAL-Freertos内存管理(2026/8/5)
c语言·单片机·rtos
zcmodeltech20 小时前
工业生产线沙盘模型多段灯带时序控制系统设计:基于STM32与Modbus RTU的连铸-热轧-镀锌全流程联动方案
stm32·单片机·嵌入式硬件·物联网·制造·嵌入式实时数据库·多分类