
很多学数字电路的同学都有过这种想法门电路这东西真值表一背不就完了吗与非门看到全1出0或非门看到有1出0反相器就更简单了输入什么就反过来。但真到了项目里你会发现事情没这么简单。举个最常见的场景。你设计一块板子想省一个与门把两个单片机的IO口直接短接心里想着“谁拉低就算谁输出0”。结果程序一跑一个引脚输出高、另一个输出低芯片烫得能煎鸡蛋逻辑还完全不对。另一个场景你第一次调I2C设备手册上写了SDA线要接上拉电阻你偷懒没接然后示波器一看SDA上的高电平连VIH都够不到CPU死活读不到ACK。这两个问题都是因为只背了真值表没搞懂CMOS门电路在输出结构上的“性格差异”。这篇文章就把CMOS门电路里那些光看真值表看不出来的东西拆开讲一讲包括你最常用的非门、与非门、或非门以及平时容易搞混的OD门、传输门、三态门。适合刚学数字电路的学生也适合搞单片机、嵌入式开发没系统补过电路课的朋友正在做硬件选型或者调试总线信号的工程师也能对照着查漏补缺。1. 为什么学了真值表还得拆开看内部电路1.1 一个让你意识到“真值表不够用”的场景先说我自己的一个经历。当年做一块多板卡的采集系统为了省一颗与门芯片我把两路上报告警信号的线直接并在一起软件里做“或”的判断。现象很诡异单块板子报警时主机确实能收到信号两块板子同时报警时主机收到的竟然还是高电平报不了警。排查了半天最后用示波器量到并接点电压只有1.1V左右一个输出高一个输出低两个输出级顶着干电平既不像是0也不像是1。那时候我才真正理解普通CMOS门的推挽输出级是不能直接“线与”的。真值表只会告诉你“非门输出输入取反”但它不会告诉你“两个非门的输出不能接在一起”。 这类坑在I2C、中断线共享、总线扩展、多设备通信里比比皆是。1.2 这几类门电路分别解决什么实际问题所以我建议初学者换个思路不要只按“逻辑功能”去记门电路要按“输出结构”去理解门电路。非门、与非门、或非门解决的是“单点对单点”的逻辑运算问题。一个输入一个输出输出级是推挽结构能主动输出强高电平和强低电平。OD门漏极开路解决的是“多个输出并一条线”的问题。它牺牲了主动输出高电平的能力换来了线与、电平转换、驱动大负载三个本事。传输门解决的是“信号通断的模拟开关”问题。它既能传数字信号也能传模拟信号而且是双向的很多锁存器、触发器内部就是用它搭的。三态门解决的是“多个数字模块共享一条总线”的问题。它平时像普通门一样强力驱动需要时又能退出总线把线让给别人。理解了这些“为什么”再去看芯片手册里的输出类型、上拉电阻要求和总线时序你就不会觉得它们只是枯燥的参数表了。2. 把CMOS当开关看反相器里的两个互补管子2.1 PMOS和NMOS两种性格相反的电子开关CMOS全称是Complementary Metal-Oxide-Semiconductor翻译过来就是“互补金属氧化物半导体”。所谓互补说的就是N型MOS管和P型MOS管在同一个电路里配合工作。你可以把MOS管简单理解成一个电压控制的开关只不过这个开关没有机械触点是靠栅极电压改变导电沟道的。注意MOS管是“电压控制”栅极输入阻抗极高基本不吸收电流。这一点和双极型晶体管BJT完全不一样也是后面很多电路特性的根源。先看看两种管子的“性格”NMOS当栅极电压比源极高出一个阈值电压Vth通常零点几伏时导通。在数字电路里我们可以粗略记忆为“输入1导通输入0截止”。它导通后允许电流从漏极流向源极也就是能把输出端往下拉。PMOS正好反过来当栅极电压比源极低一个阈值电压时导通。数字电路里粗略记忆为“输入0导通输入1截止”。它导通后能把输出端往上拉。有个不严谨但特别好用的记忆方式NMOS是“逢1导通”的开关PMOS是“逢0导通”的开关。这两个管子的导通方向刚好互补凑在一起就能搭出一个很漂亮的结构。2.2 反相器结构一个“跷跷板”反相器是CMOS门电路里最基础的结构所有其他逻辑门几乎都是在它的基础上修改出来的。它的电路连接方式是这样的PMOS管源极接VDD电源正极NMOS管源极接GND地。两个管子的漏极接在一起作为输出端Y两个管子的栅极接在一起作为输入端A。工作过程分两种情况输入A为低电平0时PMOS的栅极比源极低PMOS导通NMOS的栅极比源极高不出阈值NMOS截止。这时候输出Y被PMOS拉到VDD输出1。输入A为高电平1时PMOS截止NMOS导通。输出Y被NMOS拉到GND输出0。你看这个结构任何时刻都有且只有一个管子导通。就像跷跷板一头抬起来另一头必然压下去。这就是“互补CMOS”二字的由来。稳定状态下从VDD到GND之间没有直流通路所以CMOS门静态功耗趋近于零。这跟TTL电路完全不同TTL即使输出不变内部也在消耗电流。2.3 静态功耗与动态功耗CMOS省电的底牌既然稳定时总有一只管子截止VDD到GND没有电流通路CMOS的静态功耗就只剩下晶体管的漏电流这个值在常温下非常小微安甚至纳安级别。这是CMOS能成为数字芯片主流的根本原因之一。那CMOS什么时候耗电主要在两个动态阶段对负载电容充放电。输出从0变1时要给下一级输入电容和走线寄生电容充电从1变0时要放电。这个功耗和频率成正比公式就是著名的P C × V² × f。翻转瞬间的贯通电流。输入信号从0到1变化的过程中必然经过PMOS和NMOS同时导通的那个电压区间VDD到GND会短暂出现一个电流尖峰。频率越高这个尖峰出现得越频繁动态功耗越大。所以与其纠结静态功耗不如关注输入信号的翻转频率和沿速率。这也是为什么低功耗设计里强调“没事别让时钟翻转”。2.4 电压传输特性和噪声容限CMOS抗干扰的底气如果把CMOS反相器的输入电压从0慢慢扫到VDD同时记录输出电压你会发现它的电压传输曲线在VDD/2附近几乎是竖直下降的。这意味着输入只要稍微偏离中间点输出就会很快被拉到电源轨附近输出电平非常“干净”要么接近0V要么接近VDD。因此CMOS逻辑门的高低电平定义和TTL不太一样。比如3.3V的CMOS系列典型VIH输入高电平阈值大约是0.7×VDDVIL输入低电平阈值大约是0.3×VDD。相比TTL那只有1.5V附近的一小点阈值区间CMOS的高低电平区间宽得多。这说明什么说明CMOS门对噪声不太敏感。你想想只要输入干扰信号不超过VIL或者VIH输出状态就不会被破坏。这个“输入高电平到输出高电平之间的差值”就是噪声容限。CMOS电路的噪声容限通常可以达到零点几伏甚至更高抗干扰能力比TTL强得多。但别高兴太早。输入阻抗高、噪声容限大不等于可以随便布线。高阻抗输入端特别容易受环境干扰导致引脚电位浮动后文专门讲这个坑。3. 与非门和或非门串联并联决定逻辑3.1 从“两个开关控制一盏灯”到逻辑门先重申一条铁律CMOS门电路的上拉网络由PMOS构成和下拉网络由NMOS构成一定是互为对偶的。意思是下拉网络是串联结构上拉网络就必须是并联下拉网络是并联上拉网络就必须是串联。为什么必须这样逻辑门在任何输入组合下输出都必须有确定电平不能出现“输出悬空”或者“VDD到GND短路”。如果下拉网络是两个NMOS串联意味着需要两个NMOS同时导通才能把输出拉低那么上拉网络就必须是两个PMOS并联任何一个PMOS导通都能把输出拉高。这样在“两个NMOS同时导通”的那个输入组合下两个PMOS一定同时截止不会有直流通路。在其它组合下至少有一个PMOS导通保证输出有确定的高电平。这就是“互补”的深层含义。3.2 与非门两个NMOS串联、两个PMOS并联看与非门内部下拉网络两个NMOS管串联在输出Y和GND之间。串联意味着要两个管子同时导通Y才能被拉到0。上拉网络两个PMOS管并联在VDD和输出Y之间。并联意味着任何一个PMOS导通Y就被拉到1。逐项分析输入组合AB下拉网络NMOS串联上拉网络PMOS并联Y00截止两个PMOS都导通101截止A管截止A对应PMOS导通110截止B管截止B对应PMOS导通111导通两个PMOS都截止0逻辑表达式就是Y NOT(A AND B)口诀“全1出0”。这也是“与非门”名字的由来先与再非。你可能要问为什么与非门用得这么勤因为从晶体管角度讲它结构简单性能也好这点到3.5节再详细说。3.3 或非门两个NMOS并联、两个PMOS串联或非门是和非门对偶的结构下拉网络两个NMOS管并联在输出Y和GND之间。并联意味着任何一个NMOS导通Y就被拉到0。上拉网络两个PMOS管串联在VDD和输出Y之间。串联意味着两个PMOS必须同时导通Y才能被拉到1。输入组合分析AB下拉网络NMOS并联上拉网络PMOS串联Y00截止两个PMOS都导通101B管导通B对应PMOS截止010A管导通A对应PMOS截止011两个都导通两个都截止0逻辑表达式Y NOT(A OR B)口诀“有1出0”。注意这个“对偶”关系很有意思把与非门的上拉/下拉互换再把输入取反就变成了或非门。设计CMOS逻辑时理解了与非门或非门基本就是对其偶操作。3.4 与门、或门是怎么来的基础门加反相器市面上的74HC08是“与门”74HC32是“或门”但你要往芯片内部看它们通常是在与非门、或非门后面再接一级反相器实现的。与门 与非门 反相器或门 或非门 反相器那为什么不直接设计一个“没有内部取反”的与门因为在CMOS工艺里晶体管天然容易实现“先逻辑运算后取反”的结构。与非门、或非门的输入管可以直接接在晶体管栅极上输出端取反逻辑也简单。如果非要做一个纯与门电路会更复杂面积更大速度还可能更慢。所以你会发现标准逻辑芯片库里门电路种类很多但底层都是围绕“与非”和“或非”在转。另外加了反相器也不全是坏事。反相器本身有驱动能力恢复作用可以让输出信号的边沿更陡、带载能力更强。代价是增加了一级门延迟。所以同样一个逻辑功能用门电路搭出来的延迟和用基本与非门搭出来的延迟并不一样。3.5 串联管子的“退化”效应为什么同规模下与非门比或非门吃香这里有个教科书上不常讲、但做数字设计和时序分析时很关键的点串联的MOS管会带来额外的导通电阻和速度退化。先回忆一下晶体管特性PMOS的载流子是空穴迁移率比NMOS的电子要低大约只有一半左右。也就是说同样尺寸下PMOS的导通电阻比NMOS更大。如果再让两个PMOS串联上拉路径的总电阻就更大了。串联PMOS越多输出高电平的建立越慢上升沿越差。你对比一下与非门上拉是两个PMOS并联下拉是两个NMOS串联。PMOS并联提供了多条导电路径避免了最差的上拉情况NMOS虽然串联但本身导通能力强下拉性能受损相对小。或非门上拉是PMOS串联下拉是NMOS并联。最差的上拉路径要过两个PMOS偏偏PMOS又弱所以上拉特别慢。结论是同样驱动条件下或非门的速度通常比与非门慢功耗也更大。所以在标准数字单元库里与非门的出场率远高于或非门。很多触发器内部电路也是用与非门为核心搭的而不是或非门。如果你在FPGA或者IC设计里看到某种结构优先用与非门这不是偶然而是性能权衡的结果。4. OD门漏极开路故意不要上拉管换来三个本事4.1 推挽输出为什么不能直接并联先看普通CMOS门非门、与非门等的输出级它有一个推挽结构PMOS负责拉高导通阻抗低输出强高电平NMOS负责拉低导通阻抗低输出强低电平。这种结构驱动单点信号非常完美边沿快驱动力足。但问题就是它不能把多个输出直接并联。想象两个推挽输出的门一个输出高电平PMOS导通另一个输出低电平NMOS导通。你把它俩的输出脚短接相当于把VDD通过第一个门的PMOS直接连到了第二个门的NMOS再到GND。这两个管子导通阻抗都很低电流会瞬间飙到几百毫安甚至更大轻则输出电平被顶到中间值就像我前面说的1.1V重则芯片局部过热直接烧毁。所以我一直跟身边同事说普通GPIO之间不要随便“短接当逻辑运算用”除非你明确把其中一个配置成高阻输入或者开漏输出。否则你就是在挑战芯片的物理极限。4.2 OD门结构删掉上拉管输出变成“可下拉的悬空点”OD门全称是Open-Drain中文叫漏极开路。它的结构非常直白把普通CMOS反相器/缓冲器里的上拉PMOS管拿掉只留下NMOS下拉管输出端直接接到这个NMOS的漏极。去掉上拉管之后输出端只有两种状态NMOS导通输出被拉到GND输出低电平。NMOS截止输出既不被拉高也不被拉低呈现高阻浮空状态就像这个引脚什么都没接一样。要让这个浮空状态变成高电平必须做一件事在外部把输出端通过一个电阻接到某个正电源。这个电阻就叫作上拉电阻。如果你熟悉TTL时代会知道当时还有OC门Open-Collector集电极开路原理一模一样只是把晶体管换成了双极型三极管。OD/OC门本质上都是“外部上拉 内部下拉”的输出结构。那OD门凭什么这么有用因为它把“主动输出高电平”的权力交还给了外部电路。你想让高位电平是多少伏就把上拉电阻接到多少伏的电源上你想让多个输出并联直接把所有OD输出接到一起就行因为大家都在抢着“拉低”没有人会主动“拉高”自然就不存在推挽对顶的问题。4.3 OD门的三个经典玩法线与、电平转换、驱动负载玩法一线与逻辑。多个OD门输出直接接在一条线上再通过一颗上拉电阻接VDD。这条线的逻辑是只要有一个OD门输出低电平即NMOS导通整条线就被拉到0只有当所有OD门都截止时线才被上拉到1。这相当于对各个输出端做了一个逻辑与F Y1 · Y2 · Y3 ……最典型的应用就是I2C总线。I2C的SDA和SCL都是OD结构多个设备可以挂在同一条线上谁要传输数据就拉低这条线谁要释放总线就截止。正是这种“线与”机制让I2C不需要额外的仲裁芯片就能实现多主机通信。其它应用还包括键盘矩阵的列扫描线、多个报警输出的中断共享线、开漏比较器输出等。玩法二电平转换。因为OD门的高电平是由外部上拉电阻决定的所以我可以让上拉电阻接一个和芯片电源不同的电压。举一个最常见的场景主控MCU是3.3V供电但外设是5V逻辑。MCU的推挽输出高电平只有3.3V直接送进5V芯片可能不满足VIH要求。这时候把MCU引脚配置成开漏输出把上拉电阻接到5V那么线上高电平就是5V低电平接近0V逻辑完美转换。反向也常用5V供电的传感器输出是开漏你不想让它灌进3.3V MCU就把上拉电阻接到3.3V。这样总线电平最高只有3.3V保护了MCU。玩法三驱动负载。OD门还有一个隐藏能力它的NMOS管可以承受一定的灌电流而且上拉电源可以选得比逻辑电平更高。所以你完全可以用OD门去驱动LED、继电器、光耦这类负载。典型接法是LED一端接VDD另一端接OD输出当OD输出低电平LED导通限制电流的电阻串在LED到OD输出之间。要注意的是OD管的耐压是有上限的具体要看手册上的最大输出电压、最大灌电流别拿它去直接驱动220V交流负载那已经超出芯片安全边界了。4.4 上拉电阻怎么选公式和权衡上拉电阻选多大是OD门应用里最常遇到的问题。选小了灌电流过大功耗高输出低电平可能超VOL选大了高电平建立太慢信号边沿拉垮高速通信直接失败。推算公式其实就两个边界下限保证输出低电平时电流不超过IOL且电压不超过VOL。Rmin (VPU - VOL) / IOL上限保证所有挂在这条线上的输入引脚漏电流总和在电阻上产生的压降不把高电平拉到VIH以下。Rmax (VPU - VIH) / Itotal_leak除了直流电平还要考虑动态性能。上拉电阻和总线寄生电容会构成RC低通信号上升时间约为tr ≈ 0.847 × R × C_total。电阻越大上升沿越慢通信速率受限。我举个I2C的实际例子。高速模式下总线电容约40pFVPU3.3V要求上升时间不超过0.3μs那Rmax大约应该是0.3μs / (0.847 × 40pF) ≈ 8.8kΩ。再计算下限假设IOL3mAVOL0.4VRmin (3.3-0.4)/0.003 ≈ 967Ω。所以选2.2kΩ到4.7kΩ是比较合适的。你如果随手选个100kΩ还怪总线通信不稳定那大概率就是阻值太大导致边沿过慢。4.5 现实中哪些器件是OD门74HC07、74HC1G07、74HC05开漏输出的缓冲器/反相器。LM393、LM311、TLC372开漏/开集电极输出的比较器。I2C总线相关器件几乎所有I2C设备引脚都是OD需要外接上拉。许多MCU的GPIO可以配置成开漏模式比如STM32的GPIO配置为Output Open-Drain。各种开漏中断输出、电源监控芯片的复位输出等。遇到这些器件先别按推挽思维想“输出高电平多少”先问自己一句它有没有上拉到没有上拉输出永远只有低电平和浮空不会有干净的高电平。5. 传输门可以双向传模拟信号的“CMOS开关”5.1 单个MOS管当开关的短板阈值损失有时候你需要的不只是“逻辑输出”而是一个可控的信号开关。比如一个模拟信号你想让它在特定时间里通过、其它时候断开。这时候能不能用单个MOS管直接开关能但性能不完美。看单个NMOS当开关控制端C为高电平NMOS导通信号从输入传到输出。当输入信号是0V时输出能跟到0V附近没问题。但当输入信号接近VDD时问题来了——NMOS导通需要栅源电压Vgs大于Vth。如果输出端要升到接近VDD而栅极电压也才VDD那么Vgs就趋近于0管子会进入截止区输出最多只能升到VDD - Vth。也就是说NMOS传低电平传得很好传高电平会损失一个阈值电压叫“传0强、传1弱”。反过来单个PMOS当开关传高电平传得很好但传低电平会损失一个阈值电压叫“传1强、传0弱”。如果只是传数字信号损失一个阈值可能还没事但后级如果也是CMOS输入可能刚好满足不了VIH导致逻辑判断出错。如果传模拟信号信号波形会直接失真这就不能忍了。5.2 互补传输门的结构两个管子并联各补各的短板传输门Transmission Gate简称TG就是为了解决单管开关阈值损失而生的。它把NMOS和PMOS并联在一起NMOS的栅极接控制信号C。PMOS的栅极接C的反相信号CB。当C1、CB0时NMOS和PMOS同时导通输入和输出之间就是一条低阻通路信号任意双向传输。 当C0、CB1时两个管子都截止输入和输出彻底断开。为什么并联就解决了问题因为输入电压在不同的区间总有一个管子承担导通任务输入电压在0V到VDD-Vth这个区间NMOS能正常导通负责“传0”输入电压在Vthp到VDD的区间PMOS能正常导通负责“传1”两个管子的导通范围合起来刚好覆盖从0到VDD的整个摆幅。所以互补传输门可以无损失地传输0到VDD之间的任意电压既没有阈值损失又是双向导通。它本质上就是一个由电压控制、双向通断、导通状态有阻值的模拟开关。注意传输门不是“0电阻导线”它是有导通电阻的一般在几百欧到几千欧具体取决于工艺、管子尺寸和输入电压。而且这个导通电阻会随输入电压变化在中点附近往往最大。这个特性在精密模拟电路里很关键不过对数字逻辑来说通常只要确保Ron足够低、不会让信号衰减到阈值以下就行。5.3 传输门的典型应用模拟多路选择器和模拟开关。芯片CD4066里面有四个独立的传输门可以用作模拟开关74HC4051则是一个8选1的模拟多路选择器里面也是靠传输门阵列实现的。音频切换、传感器信号选通、自动量程档位选择都会用到。D锁存器和D触发器的内部结构。你以为D触发器是用一堆与非门搭的其实在CMOS工艺里更常见的做法是用传输门加反相器来搭。基本思路是这样当时钟为高时传输门导通输入数据直接送到存储节点当时钟变低时传输门断开存储节点的数据就被反馈反相器锁存住。主从D触发器就是两级这样的锁存器级联。所以你会发现传输门虽然平时交流得少但它在整个数字芯片里无处不在频率高得惊人。采样保持电路。ADC的采样保持前端就是一个传输门加一个保持电容。采样阶段传输门导通电容电压跟随输入保持阶段传输门断开电容把电压保持住。模拟开关性能直接决定了ADC的采样精度。各种可配置连接、可编程逻辑、复位和时钟门控。比如FPGA内部的可编程开关盒很多就是靠传输门或三态缓冲器实现的可配置连接。5.4 用传输门的几个注意事项信号幅度不能超过电源电压。传输门的体二极管在输入电压高于VDD或低于GND时会正向导通产生大电流这在模拟开关设计里一定要避免。控制信号要干净。C和CB必须是“完整”的0和VDD如果控制信号本身抖动或幅度不足可能让传输门进入半导通状态导致通路没有完全关断。断开时输出端是浮空的。传输门断开后输出端既不接上拉也不接下拉后续电路如果输入阻抗高也会出现悬空问题。所以开关断开时通常需要给后级一个偏置电阻。高频应用注意Ron的非线性。信号频率高了Ron变化会引入失真这时候要考虑选用Ron更小的模拟开关芯片或者增大传输门管子尺寸。6. 三态门让多个设备共用一条数字总线6.1 三态是哪三态三态门比普通门多一个状态英文叫Tri-state Output。三个状态是输出高电平1输出低电平0高阻态Z第三态“高阻”是什么意思就是输出级内部的PMOS和NMOS都被关断引脚对外既不灌电流也不拉电流近似于从电路里拔掉一样。注意三态门的高阻态和OD门的浮空态有个本质区别OD门的输出级根本没有主动上拉的能力它在整个工作过程中都只能下拉或者浮空而三态门在使能状态下是完完整整的推挽输出既能强拉高也能强拉低性能好得很。只是在禁止状态下它主动退出了总线相当于把驱动器的“手”从线上缩了回来。如果你在硬件描述语言里描述三态门典型写法是assign Y (EN) ? A : 1bz;仿真的时候你会看到Y在EN无效时呈现为一条高阻线而不是纯粹的高或低。6.2 三态门怎么实现三态门是在普通CMOS反相器或缓冲器的基础上增加一个输出使能控制信号EN实现的。具体电路有两种主要思路第一种是在输出级做手脚使能时让输出PMOS和NMOS受输入信号控制正常推挽输出禁止时强制让PMOS和NMOS都截止输出落进高阻态。第二种是在输出级前面加传输门内部逻辑信号要通过传输门才到输出驱动管的栅极禁止时用传输门把信号路径断开同时把输出管的栅极固定在截止电平。不管是哪种核心都是保证“使能时输出有强驱动能力禁止时没有任何驱动能力”。典型芯片包括74HC125四路三态缓冲器低电平使能。74HC126四路三态缓冲器高电平使能。74HC245八位双向三态总线收发器DIR控制方向OE控制使能。74HC541八路三态缓冲器常用于地址总线隔离。单片机GPIOIO配置为输出模式、输入模式或者高阻模式本质上也有三态能力。6.3 总线共享与竞争风险三态门最大的价值就是让多个设备可以分时共享一条数字总线。想象一个带8位数据总线的单片机系统CPU要和多个外设通信。每个外设的数据线都挂在这8根线上但它们不能同时往线上输出数据。CPU通过地址译码产生一个片选信号哪个外设被选中它里面的三态缓冲器就把数据放到总线上其它外设的三态缓冲器必须处于高阻态相当于没接。如果没有三态门而用普通推挽门那只要两个外设同时输出就变成了我前面说的“推挽对顶”总线直接崩溃。所以三态门是所有存储器、总线缓冲器、外设接口芯片的命门。但是三态门也有一个著名的坑总线竞争英文叫Bus Contention。如果两个三态门同时使能一个输出1一个输出0就会形成从VDD到GND的低阻通路产生很大的瞬态电流。轻则数据损坏重则触发闩锁效应Latch-up把芯片彻底烧坏。所以设计总线时使能逻辑必须保证“唯一性”。地址译码器的输出最好做到同一时刻只有一个有效使能也就是“独热码”风格。切换总线的设备时还要遵从一个原则先让旧设备禁能再让新设备使能中间留一点空窗期哪怕只有几十纳秒。这个时序在FPGA里和普通逻辑电路里都要刻意留出来。6.4 三态总线上的悬空问题与实用技巧三态门全部禁能时总线就没人驱动了你说它悬空严格说也不完全悬空因为总线上还有寄生电容和所有挂载芯片的输入漏电流。但这些电流很小不足以把总线稳定在某个确定电平。CMOS输入的栅极阻抗又极高悬空引脚会像一根天线附近有任何电磁干扰都可能耦合出随机电平。这会造成什么后果可能让某个外设的输入引脚读到随机的电平增加动态功耗甚至会反复触发输入保护二极管时间长了影响可靠性。解决办法在总线上加一个高阻值上拉电阻或下拉电阻常见10k或100k让总线空闲时有一个确定的默认电平。有些总线和芯片自带“总线保持器”比如某些高速SRAM它会在总线空闲时把最后电平保持住防止浮空。MCU的GPIO在切换成输入模式时通常可以配置内部上拉/下拉要用好这个功能。还有一点双向总线做读写切换时方向控制信号千万不能和读写信号打架。比如读操作时你得确保外部设备的三态输出已经使能而你的主控侧可能处于输入状态写操作相反。如果方向搞反等于两个驱动器对着冲结局大多不太愉快。7. 从门电路到系统几个我踩过的坑和查手册心得7.1 拿到芯片第一件事查输出类型很多朋友看芯片手册只盯工作电压、通信协议和指令集对输出结构毫不在意。但输出结构决定了你能不能把两个芯片的输出直接并线决定了需要不需要外接上拉电阻也决定了你能驱动的负载类型。拿到一款芯片我建议你第一件事看引脚描述和DC Characteristics表重点确认三件事Output Type是推挽Push-Pull开漏Open-Drain还是三态3-State输出电压参数VOH、VOL尤其是VOL在多少灌电流下成立。最大灌电流/拉电流IOL、IOH驱动LED或继电器时特别重要。我用一张表总结三种输出结构的选择逻辑方便你平时快速对照输出结构优点缺点典型应用推挽普通CMOS门驱动能力强、边沿快、无需外部电阻不能直接并联、不能电平转换点对点逻辑信号、时钟信号OD/OC门可线与、可电平转换、可驱动负载必须外部上拉、边沿受RC限制I2C、中断共享、LED驱动、电平转换三态门可共享总线、缓冲能力强使能时序需小心、悬空需偏置数据总线、存储器扩展、双向IO选型逻辑很简单如果只是普通板级信号推挽最省事如果要多个设备共享一根事件线优先OD如果要多个数字模块共享一组并行总线优先三态。7.2 CMOS输入不能悬空这是初学CMOS时最容易忽略的坑。CMOS栅极输入阻抗极高意味着只要有一点点电荷积累栅极电压就可能浮动到任意值。如果这个浮动电压停在VIL和VIH之间输出级状态就不可控PMOS和NMOS可能同时微导通形成明显的贯通电流严重时会引起逻辑误翻转甚至闩锁。板级设计时要注意没用的逻辑门输入端要接固定电平不能悬空。比如74HC00多余的一个与非门两个输入都接到VCC或GND输出端可以悬空不用管。复位引脚、中断输入引脚如果没接上拉/下拉可能会因为干扰误触发影响系统稳定性。调试时拔掉排线如果板子上的输入引脚悬空可以先在软件里把对应GPIO配置成内部上拉或下拉防止引脚电位漂移。我在调试低功耗时经常遇到一个问题明明CPU睡了整板电流却比预期高几百微安。查来查去往往就是某个GPIO没有接固定电平悬空导致CMOS输入管产生贯通电流。接上一颗10k电阻到确定电平电流立刻降下来。这种坑很隐蔽但排查思路其实很简单——逐个引脚检查有没有“没接任何东西”的空脚。7.3 混合电压系统里的OD电平转换3.3V和5V器件共存是嵌入式系统里最常见的电平转换场景。用OD门做电平转换要注意几个细节不然很容易翻车。第一步查手册确认你手上的MCU开漏模式是否耐压5V也就是GPIO的绝对最大额定值里的电压范围。大多数5V容忍5V-tolerant引脚可以接5V上拉但普通3.3V引脚不一定能承受。如果引脚不耐压就别直接上拉5V加个MOS管电平转换电路或者专用电平转换芯片更稳妥。第二步计算上拉电阻。跟前面第4节公式一样既要保证低电平时灌电流不超限也要保证高电平时沿速度够。5V逻辑的VIH通常是2.0V或2.4V3.3V推挽输出的高电平可能够也可能不够要具体看VOH参数。如果不够把MCU输出配置成开漏上拉到5V这是最便宜可靠的做法。第三步注意方向。OD电平转换只能单向传递逻辑电平如果对方也会往你这边推信号比如双向的SDA、双向的中断请求你需要确认双方都支持开漏模式然后两边一起靠上拉电阻维持线路电平。如果一边是强推挽输出另一边是开漏推挽侧一旦输出高相当于强行给线上注入高电平开漏侧再拉低就会形成短路电流。这种问题在双向总线上特别容易踩我在调试一颗5V实时时钟芯片时吃过这个亏后来把MCU侧也配置成开漏共享总线才恢复正常。7.4 一个综合实例OD线与加三态总线的系统级设计假设你要做一个主控加多块传感器板的小系统板卡通过排线连到主控。如果你手上已经有这些门电路的基础设计就会很顺。先看中断上报。每块板子上有一路报警输出我希望任何一块报警主控都能立刻知道。方案是每块板子的报警输出都做成OD结构主控板上放一颗10k上拉电阻到3.3V所有板子的报警线直接并到INT线上。正常时所有板子的NMOS都截止INT线被上拉到高一旦有板子报警它就把INT线拉低主控检测到下降沿中断就知道有事件发生。如果想区分是哪块板子主控再通过SPI或者并口去读各板子的寄存器。这个场景里OD门的“线与”能力完美适配“多源事件合并”的需求。再看数据读取。假设主控要同时管理多块从板的状态寄存器数据线用8位并口。每块从板的数据输出端经过74HC245三态收发器接到总线上主控通过地址译码器产生各自独立的使能信号。任意时刻只有被选中那一块板子的74HC245使能输出其它几块都处于高阻这样8根数据线就可以被多块板子共享而不会互相对顶。如果换作普通推挽输出哪怕其中两块板子同时被误使能总线上就会出现不可预测的数据和电流过冲。这套方案里OD门负责“多个输入合并成一个事件”三态门负责“多个设备共享一组总线”普通CMOS门完成局部的信号整形和缓冲。你会发现真正在系统设计里起关键作用的恰恰是这些输出结构的特性而不是真值表本身。干了这么多年硬件和嵌入式我的体会是数字电路里的门电路不是背完真值表就结束的。真正让你踩坑的永远是输出结构、输入特性和板级连接。这些基础结构搞明白了很多奇奇怪怪的bug比如线上拉高却进不了中断、两块芯片一接上就发热、拔掉排线后系统功耗变大其实你都能在原理图设计阶段提前看出来不用等样板回来用示波器一通乱扫。