上拉、下拉与总线保持:别让输入引脚悬空
更新时间:2026-09-24。本文是「集成电路大类 · 芯片设计」入门层(beginner) 数字逻辑基础的一篇。前面讲了信号怎么进出管脚,这一篇回答一个常被忽视的问题:**一个没接任何东西的输入脚,到底算 0 还是 1?**答案是——不确定,而这很危险。板子焊好、程序能跑,功耗却莫名偏高,或者复位偶尔失灵,根子常常就在一只只悬空的引脚上。
本文要回答的问题
- CMOS 输入悬空时电平由什么决定?为什么会额外耗电甚至振荡?
- 上拉/下拉电阻怎么给引脚一个确定电平?阻值大小怎么选?
- 内部可配上下拉和外部电阻各适合什么场合?
- 总线保持(bus holder)是什么?它和上拉、和强驱动会不会打架?
- 开漏总线、使能脚、按键、唤醒脚、未用引脚分别该怎么处理?
一、悬空输入:不是 0,是「随机且危险」
CMOS 输入看到的是一对 MOS 管的栅极,而栅极底下是一层二氧化硅——直流意义上的绝缘体。所以输入阻抗高得惊人,典型在 10^12Ω 以上,引脚几乎不取任何直流电流。这带来一个反直觉的后果:外部什么都不接时,没有任何东西决定它的电平。栅极上那点残存电荷无处可去,引脚就靠三条途径缓慢游走:ESD 保护二极管的微小漏电、PCB 走线对附近信号的电容耦合、以及电源线和空间电磁场的串扰。它可能碰巧停在接近 0,也可能停在接近 VDD,还可能在两者之间慢慢漂移。
真正麻烦的是第三种情况:电平停在输入阈值 VIL~VIH 之间的模拟区。芯片内部的输入缓冲器(可以想成一个反相器)里有一只 PMOS 上管和一只 NMOS 下管。输入为干净的低或高时,两只管子严格轮流导通,稳态几乎不耗电;可输入停在阈值附近时,两只管子会同时部分导通,从 VDD 到 GND 开出一条直通电流通路。这只脚可能因此多耗几百微安甚至几毫安,一片芯片几十只脚都浮空,电池产品的待机时间直接被吃掉一截。更糟的是,缓冲器在阈值区增益极高,毫伏级的噪声被放大成来回跳变的非法逻辑,内部触发器看到的是一串抖动边沿;强干扰下配合引脚电容和电感,甚至可能发生振荡。所以这是一条铁律:任何输入(包括永远不用的脚)在任何时刻都必须被驱动到确定的 0 或 1。
这张图把悬空输入的因果链画成了五级:高阻浮空 → 电荷随机 → 进入缓冲器 → 上下管同开 → 漏电与抖动。要打断这条链,只需在第一级就给引脚一个确定电平,下面三种器件干的都是这件事。
这种问题在真实产品里极其隐蔽,因为它不影响功能演示。一个典型故事:某电池供电的手环样机一切正常,待机电流却比设计值高出 2mA,查遍电源芯片无果,最后发现是一处排阻在改板时被省掉,四只预留的 GPIO 全部悬空,每只恰好停在阈值区,各贡献约 0.5mA 直通电流。更阴的是这批板子有的偏高、有的偏低,因为停在哪里纯属芯片个体的漏电差异,同一套代码在不同板子上功耗能差出几倍。这类「时有时无、换板就好」的毛病,先怀疑悬空输入,命中率很高。
二、上拉/下拉:用弱电阻把电平「钉」住
最简单的办法是一只电阻。上拉电阻接在引脚与 VDD 之间,没人驱动时引脚为高;下拉电阻接在引脚与 GND 之间,悬空时引脚为低。电阻平时不耗电流——引脚被它自己拉到电源侧后两端等电位,电流为零;只有在有效驱动器把引脚强行拉到对侧电平时,电阻上才有 VDD/R 的持续电流。
于是阻值是一道抗扰与速度 ↔ 功耗的折中题:
| 阻值选择 | 抗噪能力 | 边沿速度 | 被反向驱动时的电流(3.3V 例) |
|---|---|---|---|
| 小阻值(1kΩ~4.7kΩ) | 强,噪声难撼动 | RC 充电快 | 0.7mA~3.3mA,功耗高 |
| 中阻值(10kΩ 左右) | 够用 | 适中 | 约 0.33mA,多数场景平衡 |
| 大阻值(100kΩ 量级) | 弱,对耦合敏感 | 边沿被电容拖慢 | 约 33μA,省电 |
举个实际的数:引脚和走线总有 5pF~20pF 的电容,100kΩ 配 10pF 的 RC 时间常数是 1μs,对低速按键无所谓,放到兆级以上的信号上沿就糊了;10kΩ 时降到 0.1μs,立刻可用。但反过来,一只 1kΩ 上拉被拉低时要持续吃掉 3.3mA,几十个信号同时如此就是上百毫安,板级供电都得重新算。经验上板级固定上下拉多选 10kΩ,开漏总线按电容和速率单独算,按键类用几十 kΩ。
把一笔实际账算一遍更直观。3.3V 系统、引脚加走线电容约 15pF:选 4.7kΩ 上拉时,被拉低的电流是 3.3/4700≈0.7mA,RC 时间常数约 70ns;选 47kΩ 时电流降到 70μA,时间常数却涨到 700ns。如果这只脚是每秒翻转一次的状态指示,0.7mA 的占空比有限,平均功耗尚可接受;如果是长期被低电平占用的片选,4.7kΩ 就等于常年白送 0.7mA 给电阻发热。同一个阻值,在不同信号行为下结论完全相反,这正是阻值必须按「这只脚大部分时间待在哪个电平」来选的原因。
方向则取决于希望的安全默认态。低有效复位脚、低有效片选脚一般上拉——默认不动作,上电过程中芯片不会被意外复位或误选中;高有效使能脚通常下拉。如果这只脚控制的是电机、电源开关之类有实际后果的东西,还要按「驱动失效时最安全的方向」来定,而不是图读程序方便。
很多 MCU 和 FPGA 提供内部可配的上下拉,阻值在几十 kΩ 量级,靠寄存器或配置位打开,好处是省掉外部元件、省 PCB 面积;代价是阻值随工艺、电压、温度(PVT)离散很大,数据手册只给一个很宽的范围,而且驱动偏弱。强噪声环境、高速信号、安全相关控制脚,老老实实用外部精密电阻更稳妥。
三、开漏总线为什么离不开上拉
I2C、SMBus、1-Wire 这类开漏/线与总线把事情做到了另一个极端:总线上所有器件的输出级只有一只下拉 NMOS,谁都不会主动输出高电平。任何一个器件想发 0 就把线拉低;想发 1 或者不说话,就彻底松开管子。松开之后线凭什么回到高?凭的就是 SCL/SDA 上那两只上拉电阻。没有它们,总线拉低一次之后永远趴着,通信根本不成立。「线与」这个名字也由此而来:大家各拉各的,只要有一个拉低,线就是低,不需要任何仲裁硬件。
开漏上拉的阻值不能拍脑袋,要同时满足两个约束:阻值太大,总线电容把上升沿拖得超过协议规定的上升时间(标准模式 I2C 最多 1000ns,快速模式 300ns);阻值太小,拉低时灌电流超过器件的 OL 规格(I2C 一般限 3mA),低电平抬得太高就不认了。典型 100kHz 总线用 4.7kΩ~10kΩ,400kHz 用 2.2kΩ 左右,挂机器多、线长、电容大时还得再往下取。跨电压的开漏系统,上拉电阻接到高侧电压,同一份电阻顺带完成了电平转换,这正是电平转换里 MOSFET 方案的同一约束。
按键是上拉电阻的另一个经典用法:开关一端接地,另一端接引脚并打开内部上拉。按下时引脚被短路到地,读 0;松开后由上拉成 1,不需要给按键单独供电,也不用担心按键抖动之外的任何漂移。配合数字防抖,读到的就是干净的人机事件。
四、总线保持器:用一对弱反相器「记住」上次电平
三态总线有自己特有的问题:多个驱动器轮流说话,切换的瞬间大家可能同时进入高阻,总线短暂悬空;只要这个间隙足够长,电容上的电荷被漏光,电平又开始漂移。给总线永远挂一只上拉能解决漂移,代价是每次驱动低电平都要持续灌电流,总线越宽、活动越频繁,这笔功耗越可观。
总线保持器(bus holder,也叫 keeper)是更聪明的方案:在引脚或总线节点上接一对很弱的反相器,首尾交叉耦合,构成一个微型锁存。总线最后被驱动到什么电平,这对反相器就把那个电平弱维持住;节点电荷有任何流失,它补一点点;外部想改电平,它又弱到任何正常驱动器都能轻松盖过去,且不会像上拉那样在整个低电平期间持续灌流——驱动器一旦把线推到对面,keeper 翻转后就反过来帮着维持新电平。
图里三种方案都指向同一个节点,区别在于给的默认值不同:上拉和下拉给的是人为选定的固定电平,keeper 给的是总线上出现过的最后一个电平。这个区别决定了三条使用边界:
- keeper 不保证安全默认态。上电时总线没有「最后电平」可记,若复位阶段必须为某个确定值,仍应加上拉或下拉,不能指望 keeper;
- 模拟引脚一般不能开 keeper。模拟源输出的是连续电平,弱锁存会和它互相拉扯,引入非线性和失真,ADC 输入看到的波形就不干净了;
- 开漏总线用真正的上拉,不用 keeper。开漏器件只能拉低、释放后需要一条确定的高电平通路,keeper 无法在全片器件都松开时提供协议要求的高电平。
此外上下拉和 keeper 不要在同一只脚上同时乱开——一个想钉固定电平、一个想维持最后电平,两者在电平相反时互相竞争,只会白白耗电又拖慢边沿。
五、实践清单:各类引脚对号入座
| 引脚类型 | 推荐处理 | 默认态理由 |
|---|---|---|
| 未用输入脚 | 配内部上/下拉,或外部电阻 | 杜绝悬空漏电与振荡 |
| 未用双向口 | 直接设为输出,驱动安全电平 | 最省事,不依赖任何电阻 |
| 低有效复位/片选 | 上拉(内部或外部) | 上电到固件接管前不误动作 |
| 高有效使能脚 | 下拉,或按失效安全方向定 | 避免上电毛刺误使能 |
| 唤醒脚 | 按待机默认态配上下拉 | 防止噪声误唤醒白白耗电 |
| 按键/开关 | 一端接地 + 内部上拉 + 软件防抖 | 省元件,读键可靠 |
| I2C/SMBus/1-Wire | 外部上拉到总线电压 | 开漏无主动高,无电阻不工作 |
| 模拟输入 | 既不开上下拉也不开 keeper | 避免改变被测电平与波形 |
工程上还有两个容易栽的细节。其一,内部上下拉在芯片刚上电、配置寄存器尚未写入时往往是关闭的,如果这只脚在复位阶段就必须安全(典型如复位脚和电源使能脚),不能依赖软件配置,必须用外部电阻钉死。其二,内部阻值随 PVT 离散且偏弱,汽车电子、工业现场等强噪声场合,以及高速总线,都应改用外部电阻并按电容算过边沿。上电时序期间的这些毛刺,和低功耗漏电一起,构成了待机电流超标最常见的两个来源。
六、怎么在板子上确认一只脚是否悬空
怀疑某只脚悬空,按下面三步判断,基本不会错。
- 万用表量直流电压。悬空脚常停在一个「不上不下」的读数上,比如 3.3V 系统量出 1.2V、1.8V,而且读数缓慢漂移;但要注意,万用表本身有 10MΩ 内阻,表笔一碰就可能把电平拉走,所以读数正常也不能完全排除悬空,需要结合下两步。
- 手指或螺丝刀轻触引脚(仅限低压小板,动作轻)。人体感应是很好的噪声源,如果 LED、读数或寄存器状态跟着跳变,说明这只脚没有任何确定的维持力量。
- 示波器看交流。阈值区的悬空脚在探头接入后往往能看到几十毫伏到数百毫伏的噪声带,甚至周期性振荡;干净的被驱动信号则是贴着 0 或 VDD 的平整直线,沿干净利落。
反过来验证修复也简单:接上电阻或打开内部上下拉后,电压应立刻贴死 0 或 VDD,触摸不再引起跳变,整板待机电流回落到设计值。养成「画原理图时逐只输入脚确认默认态」的习惯,比事后拿示波器捞针便宜得多。
这一篇在知识体系里的位置
本篇属于数字电路电气基础,回答「没有驱动时引脚该是什么」。向引脚结构读,前置是芯片引脚与 PAD;向输出级读,紧挨着的是三态与开漏,keeper 正是为三态切换间隙服务的;向接口读,可衔接电平转换/VCCIO、脉冲整形/防抖和矩阵键盘扫描;想弄明白阈值区为什么直通电流那么大,可深入逻辑门电气特性与噪声容限。
总结
一句话总结:CMOS 输入阻抗极高,悬空时电平由漏电和噪声随机决定,极易停在阈值区让输入缓冲的上下管同时导通,产生直通漏电、抖动甚至振荡,所以任何输入在任何时刻都必须被钉到确定电平;上拉/下拉用一只弱电阻在无人驱动时把电平定到 VDD 或 GND,阻值在抗扰速度和灌流功耗之间折中(板级常用 10kΩ),方向按上电安全默认态选,内部可配上下拉省元件但弱且随工艺离散、强噪高速要用外部电阻;开漏总线只能拉低、必须靠上拉才能回到高电平;总线保持器用一对很弱的交叉耦合反相器在三态间隙维持最后电平、且能被正常驱动轻松覆盖,但它给的是「最后电平」而非安全默认态,模拟脚和开漏总线都不适用;未用输入务必配上下拉或设为安全输出,按键用接地加内部上拉,复位、使能、唤醒脚一律按失效安全方向默认。