目录
- 前言
-
-
- [常识铺垫:MCU 眼中的世界](#常识铺垫:MCU 眼中的世界)
-
- [1. 数字信息(状态有限)](#1. 数字信息(状态有限))
- [2. 模拟信息(连续可变)](#2. 模拟信息(连续可变))
- [为什么 MCU 都要学?](#为什么 MCU 都要学?)
- [1.1 核心组件勘误:TTL 施密特触发器](#1.1 核心组件勘误:TTL 施密特触发器)
- [1.2 MCU 内部宏观架构与 GPIO 布局](#1.2 MCU 内部宏观架构与 GPIO 布局)
-
- [1.2.1 GPIO 端口与引脚的层级关系](#1.2.1 GPIO 端口与引脚的层级关系)
- [1.2.2 单个引脚背后的双重电路](#1.2.2 单个引脚背后的双重电路)
- [1.3 施密特触发器的抗干扰原理](#1.3 施密特触发器的抗干扰原理)
-
- [1.3.1 现实信号的"不完美"](#1.3.1 现实信号的“不完美”)
- [1.3.2 迟滞特性与双阈值机制](#1.3.2 迟滞特性与双阈值机制)
- [1.3.3 波形整形过程](#1.3.3 波形整形过程)
-
- [二、四种 GPIO 输入模式详解](#二、四种 GPIO 输入模式详解)
-
- [2.1 上拉输入模式](#2.1 上拉输入模式)
-
- [2.1.1 电路状态](#2.1.1 电路状态)
- [2.1.2 工作逻辑](#2.1.2 工作逻辑)
- [2.2 下拉输入模式](#2.2 下拉输入模式)
-
- [2.2.1 电路状态](#2.2.1 电路状态)
- [2.2.2 工作逻辑](#2.2.2 工作逻辑)
- [2.3 浮空输入模式](#2.3 浮空输入模式)
-
- [2.3.1 电路状态](#2.3.1 电路状态)
- [2.3.2 工作逻辑](#2.3.2 工作逻辑)
- [2.4 模拟输入模式](#2.4 模拟输入模式)
-
- [2.4.1 电路状态](#2.4.1 电路状态)
- [2.4.2 工作逻辑](#2.4.2 工作逻辑)
- 三、数据流向与复用功能机制
-
- [3.1 数据的两条去向](#3.1 数据的两条去向)
- [3.2 复用功能的特殊性](#3.2 复用功能的特殊性)
- 结语


🎬 云泽Q :个人主页
🔥 专栏传送入口 : 《C语言》《数据结构》《C++》《Linux》《蓝桥杯系列》《笔试算法》《AI赋能》《STM32》
⛺️遇见安然遇见你,不负代码不负卿~
前言
大家好啊,我是云泽Q,欢迎阅读我的文章,一名热爱计算机技术的在校大学生,喜欢在课余时间做一些计算机技术的总结性文章,希望我的文章能为你解答困惑~
常识铺垫:MCU 眼中的世界
在深入 GPIO 的寄存器配置之前,我们需要先达成一个共识:单片机(MCU)是如何理解这个世界的?
归根结底,我们现实生活中的信息,只分为两类:
1. 数字信息(状态有限)
这类信息是可以量化的,通常只有"有"或"无"、"开"或"关"两种确定的状态。
- 生活案例:电梯门关好没?汽车安全带系好没?共享单车锁好没?手机静音没?门铃被按下了没?
- 特点:非 0 即 1,逻辑清晰,没有中间地带。
2. 模拟信息(连续可变)
这类信息是连续变化的,随时间推移可以取无穷多个数值。
- 生活案例:洗澡水的冷热程度、手机剩余电量的百分比、奶茶店背景音乐的音量大小、早高峰地铁的拥挤程度、骑自行车的速度快慢、吹风机的风力档位。
- 特点:平滑过渡,丰富细腻,但也更复杂。
为什么 MCU 都要学?
随着信息时代的到来,计算机和单片机层出不穷。但请记住,这些设备归根结底是为人服务的。
- 为了给你提供打车服务,它必须获取你的位置(模拟/数字混合);
- 为了给你做健康检查,它必须获取你的体温和心跳(模拟信号);
- 为了自动调节室温,空调必须感知房间温度(模拟信号)。
为了处理这两类截然不同的信息,硬件工程师和科学家们发明了复杂的电路,高校也因此开设了两门著名的"天书"课程------《数字电路》和《模拟电路》。开设这两门课程的原因,就是教我们在计算机世界里,如何处理人类世界的这两种信息。
虽然 MCU 最终需要处理模拟和数字两种信息,但在本章关于 GPIO 输入模式的探讨中,我们将暂时把复杂的模拟信息 放在一边,专注于数字信息的处理逻辑。
1.1 核心组件勘误:TTL 施密特触发器
在之前分析 GPIO 输出模式时,已经搞定了输出电路的那一部分。现在,我们将视线转移到输入电路上。大家在看参考手册或者课件电路图时,会看到一个位于输入路径前端的三角形符号组件。请注意,这里有一个常见的翻译纰漏需要纠正:

- 错误翻译:在部分中文参考手册中,这个组件被翻译为"肖特基触发器"。
- 正确名称 :在英文原版手册及标准电子学术语中,它被称为 TTL Schmitt Trigger ,即 TTL 施密特触发器。
"肖特基"通常指代二极管(Schottky Diode),而这里用于信号整形的绝对是"施密特触发器"。大家在阅读文档或编写代码注释时,请务必使用正确的术语,以免产生概念混淆。我们在后续的文章中也会统一更正为"施密特触发器"。

1.2 MCU 内部宏观架构与 GPIO 布局
要理解输入电路,不能只盯着一个引脚看,必须建立 MCU 内部的宏观视角。
1.2.1 GPIO 端口与引脚的层级关系
整个 MCU 内部通过 APB2 总线接入了各种各样的 GPIO 端口组。以 STM32 为例,通常包含 GPIOA、GPIOB 等多组端口(共 7 组)。
- 端口组:每一组(如 GPIOA)对应一组完全相同的寄存器配置。
- 引脚数量:每一个 GPIO 端口组包含 16 个引脚(Pin 0 - Pin 15)。
- 总规模 :7 组 × 16 个 = 112 个 GPIO 引脚。

1.2.2 单个引脚背后的双重电路
当我们把每一个引脚(例如 PA0)进行电路级展开时,你会发现每个引脚背后都挂载了两套独立的电路系统:
- 输入电路:负责采集外部信号。
- 输出电路:负责向外驱动信号。
这两套电路是互斥的,同一个引脚在同一时刻只能作为输入或输出中的一种模式工作。我们在研究输入模式时,会将下方的输出驱动部分(MOS管等)暂时忽略,专注于上方的输入通路。



1.3 施密特触发器的抗干扰原理
为什么数字输入信号非要经过施密特触发器?这是理解 GPIO 输入稳定性的核心。
1.3.1 现实信号的"不完美"
理想的数字信号应该是完美的方波:高电平就是稳定的 3.3V,低电平就是稳定的 0V,跳变瞬间完成。但在实际物理世界中,信号往往是"脏"的:

- 抖动与毛刺:由于电磁干扰或机械按键的抖动,信号线上会叠加高频噪声。
- 缓慢变化的斜坡 :信号从低到高或从高到低的跳变往往不是垂直的,而是带有斜率的斜坡。

如果直接将这种带有噪声或斜坡的信号送入 CPU,CPU 可能会在临界电压附近频繁误判,导致读取到的数据在 0 和 1 之间疯狂跳变。
1.3.2 迟滞特性与双阈值机制
施密特触发器之所以能解决这个问题,是因为它具有迟滞特性。它内部设定了两个不同的阈值电压,而不是像普通比较器那样只有一个阈值:
- 正向阈值电压 ( V T + V_{T+} VT+):当输入信号从低电平上升,必须超过这个较高的电压值,输出才会翻转为高电平(逻辑 1)。
- 负向阈值电压 ( V T − V_{T-} VT−):当输入信号从高电平下降,必须低于这个较低的电压值,输出才会翻转为低电平(逻辑 0)。
这两个阈值之间的区域被称为迟滞区域 。


1.3.3 波形整形过程
让我们模拟一下信号处理过程:
- 上升阶段 :外部输入一个带有噪声的斜坡信号。当电压爬升超过 V T + V_{T+} VT+ 时,施密特触发器输出瞬间跳变为高电平。此后,即使信号因为噪声回落了一点点,只要没跌破 V T + V_{T+} VT+,输出依然保持高电平。
- 下降阶段 :当信号开始下降,即使跌破了 V T + V_{T+} VT+,输出也不会变。只有当电压继续下跌,击穿底部的 V T − V_{T-} VT− 时,输出才会瞬间跳变为低电平。
- 噪声免疫 :假设信号在 V T + V_{T+} VT+ 和 V T − V_{T-} VT− 之间的迟滞区域内来回跳动(例如机械按键抖动),施密特触发器的输出状态是锁死不变 的。

通过这种机制,原本边缘模糊、充满毛刺的模拟波形,被"整形"成了边缘陡峭、干净利落的数字方波,确保了 ARM CPU 读取到的 IDR 寄存器数据是稳定可靠的。
二、四种 GPIO 输入模式详解
GPIO 的输入模式主要通过控制内部的上拉/下拉电阻开关来实现。根据外部电路的不同需求,我们可以配置为以下四种模式。
2.1 上拉输入模式
2.1.1 电路状态
- 内部开关:闭合连接 VDD 的上拉开关,断开连接 VSS 的下拉开关。
- 等效电路 :引脚通过一个内部电阻(通常 30kΩ-50kΩ)连接到电源正极(VDD)。

2.1.2 工作逻辑
-
外部悬空时 :由于内部上拉电阻的存在,引脚电平被默认拉高到 VDD。此时施密特触发器检测到高电平,输入数据寄存器(IDR)读出的值为 1 。这解决了引脚悬空导致电平不确定的问题。

-
外部输入低电平时 :当外部电路(如按下的按键)将引脚接地(GND)时,电流从 VDD 经过上拉电阻流向 GND。此时引脚处的电压被拉低至接近 0V。施密特触发器检测到低电平,IDR 读出值为 0 。



- 注意 :此时,上拉电阻两端承受了完整的电源压降(即 V D D − 0 V V_{DD} - 0V VDD−0V)。由于此类片内上下拉电阻的阻值通常较大(普遍在 30kΩ~50kΩ 之间),根据欧姆定律( I = U / R I=U/R I=U/R),回路中仅会有微弱的电流流过。这也是其被称为"弱上拉/弱下拉"的原因。
关键点在于:虽然内部有上拉电阻试图将电位拉高,但由于外部输入信号提供了极低阻抗的对地通路(强下拉),根据分压原理,引脚处的实际电位会被外部信号强行钳位在低电平(0V),而不会被内部的上拉电阻拉高。
- 注意 :此时,上拉电阻两端承受了完整的电源压降(即 V D D − 0 V V_{DD} - 0V VDD−0V)。由于此类片内上下拉电阻的阻值通常较大(普遍在 30kΩ~50kΩ 之间),根据欧姆定律( I = U / R I=U/R I=U/R),回路中仅会有微弱的电流流过。这也是其被称为"弱上拉/弱下拉"的原因。
-
外部输入高电平时 :外部直接给高电平,引脚维持高电平,IDR 读出 1 。

2.2 下拉输入模式
2.2.1 电路状态
- 内部开关:断开连接 VDD 的上拉开关,闭合连接 VSS 的下拉开关。
- 等效电路 :引脚通过一个内部电阻连接到地(VSS/GND)。

2.2.2 工作逻辑
-
外部悬空时 :内部下拉电阻将引脚电平默认拉低到 GND。施密特触发器检测到低电平,IDR 读出值为 0 。

-
外部输入高电平时 :外部电路提供高电平(VDD),电流从外部流入,经过下拉电阻流向 GND。引脚电压被拉高至接近 VDD。施密特触发器检测到高电平,IDR 读出值为 1 。



同理因欧姆定律的存在,引脚处电压也不会因下拉电阻拉低
-
外部输入低电平时 :外部接地,引脚维持低电平,IDR 读出 0 。

2.3 浮空输入模式
2.3.1 电路状态
- 内部开关 :上拉开关和下拉开关全部断开。
- 等效电路 :引脚内部既不上拉也不下拉,处于高阻态。


2.3.2 工作逻辑
- 完全依赖外部 :引脚的电平状态完全由外部电路决定。
- 外部给高,就读到 1。
- 外部给低,就读到 0。
- 风险点:如果外部电路也是悬空的(没有接任何确定的电平源),那么引脚就会处于"浮空"状态。此时引脚极易受到周围电磁环境的干扰,感应出杂波电荷,导致施密特触发器在高低电平之间随机翻转,读出不可预测的数据。
- 应用场景:通常用于外部已经有明确上下拉电阻的电路(如 I2C 总线的 SDA/SCL 线,外部已有上拉),或者是标准的通信接口(如 USART RX),避免内部电阻干扰外部信号电平。
2.4 模拟输入模式
2.4.1 电路状态
- 数字通路切断 :连接施密特触发器的开关断开。这意味着数字输入路径被彻底关闭,施密特触发器不再工作,也不会消耗动态功耗。
- 模拟通路开启 :引脚直接通过一条模拟线路连接到片上外设(主要是 ADC 模数转换器)。



2.4.2 工作逻辑
- 用途:专门用于 ADC 采集。
- 原理:我们需要采集的是连续的电压值(如传感器输出的 1.5V、2.3V),而不是非 0 即 1 的数字信号。如果开启施密特触发器,它会把所有高于阈值的电压都强行变成 1,低于阈值的变成 0,这就丢失了模拟信号的细节。
- 数据流向 :在模拟模式下,CPU 无法通过读取 GPIO 的输入数据寄存器(IDR)来获取数据。ADC 外设会直接从这条模拟通路上"抓取"电压值进行转换。
三、数据流向与复用功能机制
理解了单引脚的输入模式后,我们还需要搞清楚这些数据最终去了哪里。
3.1 数据的两条去向
当信号经过施密特触发器整形为标准的数字 0/1 信号后,它会面临两个去向的选择:

-
供 CPU 读取(通用 GPIO 模式) :
信号进入 输入数据寄存器 (IDR)。ARM CPU 可以通过总线访问这个寄存器,程序里写代码读取 IDR 的某一位,就能知道当前引脚是高还是低。这是做按键检测、开关量读取时的路径。
-
供片上外设复用(复用功能模式) :
信号不经过 IDR,而是直接通过"复用功能输入"通道,输送给其他片上外设(如 USART 的接收端、SPI 的 MISO 端、I2C 的 SDA 端等)。
3.2 复用功能的特殊性
这里有一个非常容易混淆的概念点,请大家务必注意:
当引脚被配置为复用功能(例如作为串口的 RX 接收引脚)时:
- CPU 读不到 IDR:虽然物理线路上信号确实经过了施密特触发器,但数据并没有锁存到 GPIO 的 IDR 寄存器中供 CPU 随意读取。
- 外设直接获取:串口外设(USART)有自己独立的接收移位寄存器和数据寄存器。它会直接从复用通路上获取这个 0/1 信号进行解码。
- 结论:如果你把引脚配成了串口 RX,你在代码里去读 GPIOA->IDR,是读不到串口数据的(或者读到的不是实时的串口波形)。你必须去读 USART 的数据寄存器才能拿到通信内容。
同理,如果是 SPI 或 I2C 的复用输入,也是由对应的 SPI/I2C 硬件模块直接接管数据流,而不是靠 CPU 轮询 GPIO 寄存器来搬运数据。
结语
