本文基于江科大STM32入门教程第3章,结合《STM32F103xx参考手册》和实际实验,梳理GPIO的核心知识点。写这篇文章的过程中,我对"推挽输出"和"开漏输出"的区别有了更深的理解,让朋友们对GPIO有一个初步的理解,希望能帮到同样刚入门的朋友。如有错误,欢迎评论区指正!
一、什么是GPIO?
GPIO(General Purpose Input/Output),即通用输入输出端口。简单来说,就是STM32芯片上那些可以人为控制高低电平的引脚。
STM32F103C8T6有48个引脚,其中37个可以作为GPIO使用(PA0~PA15、PB0~PB15、PC13~PC15等)。每个GPIO引脚都可以通过软件配置为不同的工作模式,来实现输入检测(如按键)或输出控制(如LED、蜂鸣器)等功能。
二、GPIO的8种工作模式
这是江科大课程里的重点,也是新手最容易混淆的地方。STM32的每个GPIO引脚都可以配置为8种工作模式,分为4类:

上图截取自《STM32F10xxx参考手册》Table 185,是标准库中 GPIO_Mode 的宏定义值。可以看到,8种模式在库函数中被明确定义为不同的枚举常量,我们在代码中直接调用这些宏即可,不需要去记具体的寄存器位。
2.1 输出模式详解

上图来自参考手册图16,展示了输出模式的内部结构,是理解推挽/开漏的关键:
- P-MOS(上方):导通时引脚接VDD,输出高电平(3.3V)
- N-MOS(下方):导通时引脚接VSS(GND),输出低电平(0V)
推挽输出(Push-Pull):P-MOS和N-MOS轮流导通。
输出1时P-MOS开、N-MOS关 → 引脚接VDD;
输出0时P-MOS关、N-MOS开 → 引脚接VSS。
就像两个人"推"和"挽"着引脚,所以叫推挽。
开漏输出(Open-Drain):P-MOS始终关闭,只有N-MOS工作。
输出1时N-MOS关,引脚悬空(高阻态);
输出0时N-MOS开,引脚接VSS。
就像水龙头的"漏口"是打开的,必须外接一根管子(上拉电阻)才能出水(出高电平)。
① 推挽输出(GPIO_Mode_Out_PP)
最常用的输出模式。输出高电平时,P-MOS导通,引脚直接接VCC(3.3V);输出低电平时,N-MOS导通,引脚直接接GND。
-
优点:驱动能力强,高低电平都很稳定
-
缺点:不能实现"线与"(多个设备共用一根线)
-
典型应用:点亮LED、驱动蜂鸣器、控制继电器
② 开漏输出(GPIO_Mode_Out_OD)
输出高电平时,P-MOS不导通,引脚处于高阻态(相当于断开);输出低电平时,N-MOS导通,引脚接GND。
-
优点:可以实现电平转换(外接上拉电阻到5V就能输出5V);支持"线与"
-
缺点:高电平驱动能力弱,必须外接上拉电阻
-
典型应用:I2C总线、需要5V电平兼容的场景
💡 我的理解:推挽输出是STM32自己"推"出高电平;开漏输出是STM32只负责"拉低",高电平要靠自己外接电阻"拉"上来。
上图来自参考手册图17,展示了复用功能配置的内部结构。和普通输出模式(图16)对比,最大的区别在左下角:
- 普通输出:信号来自 输出数据寄存器(CPU控制)
- 复用输出:信号来自 片上外设(如USART、SPI、I2C硬件模块自动控制)
这就是为什么配置串口TX、SPI的MOSI时,必须用 GPIO_Mode_AF_PP,而不是 GPIO_Mode_Out_PP —— 因为此时引脚不由你的程序直接控制,而是由USART/SPI硬件外设来驱动。
输入侧同理:复用功能输入会把信号送给片上外设,而不是输入数据寄存器。
③ 复用推挽输出(GPIO_Mode_AF_PP)& ④ 复用开漏输出(GPIO_Mode_AF_OD)
和普通推挽/开漏的区别在于:引脚不由CPU直接控制,而是由片上外设(如USART、SPI、I2C)控制。比如USART1的TX引脚,必须配置为复用推挽输出。
2.2 输入模式详解

上图来自《STM32F10xxx参考手册》图15,展示了输入模式的内部结构:
- TTL肖特基(英文版翻译过来应该是施密特,这里应该是翻译错误)触发器:将模拟电平转换为数字电平(0或1)
- 上/下拉电阻:通过开关控制是否接入,对应上拉输入和下拉输入
- 浮空输入:上下拉电阻都断开,引脚电平完全由外部决定
💡 我的理解:如果把引脚比作一根导线,浮空输入就是这根导线"悬在空中",很容易受周围电磁干扰;而上拉输入就是在这根导线和VDD之间接了一个电阻,默认把它"拉"到高电平。
① 浮空输入(GPIO_Mode_IN_FLOATING)
引脚不接上拉也不接下拉电阻,电平完全由外部决定。如果外部没有明确驱动,引脚电平会飘忽不定(容易受干扰)。
-
适用场景:外部电路已经有上下拉电阻时
② 上拉输入(GPIO_Mode_IPU)
芯片内部接了一个上拉电阻(约30~50kΩ),默认状态下引脚为高电平。当外部拉低时,读到的就是低电平。
-
适用场景:按键检测最推荐的模式,按键另一端接GND即可
③ 下拉输入(GPIO_Mode_IPD)
芯片内部接了一个下拉电阻,默认状态下引脚为低电平。

上图来自参考手册图18,是模拟输入模式的内部结构。
- TTL肖特基(英文版翻译过来应该是施密特,这里应该是翻译错误)触发器被关闭(图中标注"关"),模拟信号不经过数字转换
- 上下拉电阻全部断开,避免对模拟信号产生分压影响
- 引脚电平直接送入片上的 ADC外设 进行采样
💡 这就是为什么做ADC采集时,必须配置为 GPIO_Mode_AIN,如果错配成浮空输入,触发器会把模拟电压"截断"成0或1,采集结果就全错了。
④ 模拟输入(GPIO_Mode_AIN)
引脚直接连接到片上的ADC模块,不经过施密特触发器,用于采集模拟电压信号。
三、总结
通过本文的梳理,我们可以将STM32 GPIO的8种工作模式归纳为以下核心要点:
- 输出模式:分为普通输出和复用输出,核心区别在于信号源是CPU还是片上外设。
- 推挽输出:驱动能力强,高低电平稳定,适合驱动LED、蜂鸣器等负载。
- 开漏输出:可实现电平转换和“线与”功能,常用于I2C等总线通信。
- 输入模式:关键在于内部上/下拉电阻的配置。
- 浮空输入:电平由外部决定,易受干扰,适用于外部已有上下拉的场景。
- 上拉/下拉输入:内部电阻提供默认电平,是按键检测的推荐配置。
- 模拟输入:信号直通ADC,用于采集模拟电压,必须正确配置以避免数字电路干扰。
理解这些模式的关键在于对照参考手册中的结构图,明确信号路径和开关状态。实际开发中,根据外设需求(如USART、I2C、ADC)选择对应模式,并注意推挽与开漏、普通与复用的区别,可以避免很多硬件层面的调试问题。
希望这篇梳理能帮助你建立起对STM32 GPIO工作模式的清晰认知。实践出真知,多动手配置、测量,理解会更加深刻。
持续更新学习笔记,欢迎大家点赞收藏!



