
做数字电路调试这些年我发现一个挺有意思的现象很多朋友手里堆了一堆 74 系列芯片但真到用的时候翻来覆去只会用 74HC595 点流水灯、用 74HC138 做位选遇到需要“同时监控一大堆信号还要抢优先级”的场景就不知道该怎么办了。这次要讲的 74HC148就是专治这种需求的芯片。它本身是一个 8 线-3 线优先编码器输入 8 个信号输出 3 位二进制编码而且自带优先级判定逻辑。但更实用的玩法是拿两片 74HC148 拼成一个 16 线-4 线优先编码器把输入通道扩展到 16 路编码输出扩展到 4 位。这个电路在做键盘矩阵、多路中断请求、多传感器优先级仲裁的时候都特别顺手。文章会从芯片内部逻辑讲起把为什么要级联、输出怎么拼接、电路图怎么画、面包板怎么搭、常见坑怎么避全部过一遍。不管你是刚入门数字电路还是已经能独立做小项目只要想把输入通道数扩上去这篇文章应该都能帮到你。1. 先把 74HC148 这颗芯片吃透1.1 优先编码器到底是什么东西普通编码器的逻辑很简单输入端有信号输出端就给对应的二进制码。问题在于如果两个输入同时有效呢普通编码器会因为内部逻辑互相打架而输出一个混乱的编码。优先编码器天生就是解决这个问题的。它做了两件事一是给了每个输入分配了固定的优先级一般是编号大的优先级高二是哪怕多个输入同时有效它也只会输出优先级最高的那个输入对应的编码其他信号全部忽略。举个例子假设输入 I7 和 I2 同时接地74HC148 会认为 I7 比 I2 重要最终输出的编码就对应 I7。这在现实世界里非常有意义——一个系统里往往不是所有事件都同等紧急比如电机过流和按键按下这两个中断同时来的时候肯定要先处理电机过流。16 线-4 线优先编码器的本质就是把这种能力从 8 路扩展到 16 路让一个系统能处理更复杂的信号采集和优先级判断任务。1.2 74HC148 引脚和真值表别被“反码”坑了74HC148 是 16 脚 DIP 或 SOIC 封装常用引脚功能如下I0 到 I78 个输入低电平有效。也就是说输入信号接地或拉低时表示这一路有请求。输入悬空时默认认为是无效。A0 到 A23 位编码输出但注意是反码输出不是原码。后面我会专门解释这一点。EI使能输入低电平有效。只有 EI 接低芯片才工作。EI 接高时芯片被禁用输出全部为高。EO使能输出低电平有效。当芯片被使能但没有任何一路输入有效时EO 输出低电平。GS组信号输出低电平有效。只要输入里至少有一路有效GS 就输出低电平。它用来区分“没请求”和“第 0 路有请求”这两种情况。它的真值表核心逻辑可以简化成一句话在有输入的前提下输出等于当前最高优先级输入编号的反码。比如 I7 有效输出 A2A1A0 就是 000I6 有效输出就是 001I1 有效输出就是 110I0 有效输出是 111。这里最大的坑就是“反码”。很多新手第一次拿到 74HC148按直觉以为 I0 有效会输出 000结果示波器一测是 111马上就懵了。其实这是芯片故意设计的反码输出配合低电平有效的输入能让外部逻辑少掉一堆反相器。如果你想得到常规的正逻辑编码只要在输出端再加一级反相器就行。2. 16 线-4 线级联的设计思路2.1 为什么要级联而不是直接选 16 输入的芯片可能有人会问有没有直接做 16 线-4 线的芯片有是有但不常见而且价格和采购渠道都比较麻烦。74HC148 这种通用芯片几毛钱一片全世界都在用资料多、替代型号多手边随便就能翻出来。用两片 8 线-3 线的 148 拼成 16 线-4 线成本低、灵活度高还能顺便理解芯片级联的通用思路以后遇到其他需要扩展的芯片比如 74HC138、CD4511方法论可以直接迁移过去。级联的核心思路是把 16 路输入分成两组。第一片处理 I0 到 I7称为低组第二片处理 I8 到 I15称为高组。两片芯片通过 EI 和 EO 串起来形成一个优先级链高组芯片享有更高的整体优先级只要 I8 到 I15 里有任何一个有效低组芯片就自动被屏蔽掉输出完全由高组接管。2.2 级联的具体接法具体接法是这样的先把两片 74HC148 的电源和地接好VCC 接 5VGND 接地。高组芯片的 EI 直接接地让它始终处于使能状态。因为高组的优先级最高它必须一直在线监控 I8 到 I15 的变化。高组芯片的 EO 输出接到低组芯片的 EI 输入。这样一来高组芯片只要检测到任何一路输入有效它的 EO 就会输出高电平把低组芯片禁掉。反之如果高组芯片觉得所有输入都是空闲的EO 输出低电平低组芯片就正常使能开始处理 I0 到 I7。低组芯片的 EO 可以暂时空着不用接。通过这一根 EO 到 EI 的连线两片芯片天然形成了优先级链条不再需要额外加锁存器、比较器逻辑非常干净。2.3 编码输出怎么拼成 4 位现在两片芯片各自都有 A2、A1、A0 三根线你需要把它们合并成最终的 Y3、Y2、Y1、Y0 四位输出。这里不能直接硬连。原因很简单两片芯片的输出都是推挽结构如果低组输出低电平、高组输出高电平两根线直接短接就会打架轻则电平被拉到一个不确定的中间值重则长时间工作发热甚至损坏芯片。正确做法是加一级组合逻辑。我推荐用与非门做合并原因后面讲这里先把公式列出来Y2 ~(U1_A2 U2_A2)Y1 ~(U1_A1 U2_A1)Y0 ~(U1_A0 U2_A0)其中 U1 表示低组芯片U2 表示高组芯片。用一个 74HC00内部有 4 个 2 输入与非门刚好能完成这三个输出位的合并总共只需要 3 个与非门。那最高位 Y3 呢Y3 的本质是区分当前有效输入到底在低组还是高组。只要高组芯片有输入有效也就是说 I8 到 I15 里有任何一路被激活Y3 就应该输出 1。而 74HC148 的 GS 引脚正好提供了这个信息高组芯片的 GS 为低时表示当前有输入请求。所以 Y3 可以直接取高组 GS 的反相信号。如果你手里有 74HC04 反相器可以用一个非门搞定。如果没有也可以用 74HC00 里剩下的那个与非门把 GS 信号同时接到与非门的两个输入端就等价于一个反相器。这样一颗 74HC00 就能把三路合并和最高位全部搞定不用额外加芯片。2.4 完整电路图的连接关系总结为了方便画图我把完整连接关系按模块整理一下输入模块I0 到 I7 接低组 148 的 I0 到 I7I8 到 I15 接高组 148 的 I0 到 I7。所有输入信号低电平有效。使能模块高组 148 的 EI 接地高组 148 的 EO 接低组 148 的 EI低组 148 的 EO 悬空。输出模块低组和高组的 A2A1A0 分别接入 74HC00 的三个与非门与非门输出为 Y2Y1Y0。高组的 GS 接入非门非门输出为 Y3。这四行连接关系就是整个电路图的骨架。只要你按这个逻辑去连线哪怕不看原理图也能在面包板上一步步搭出来。3. 从原理到实物面包板实操记录3.1 元件清单和准备工作在动手之前先把东西备齐。我这里列出的是十六路输入完整状态下需要的元件实际测试时你手头没那么多按键也可以分步验证。74HC148 两片74HC00 一片74HC04 一片如果想让输出全部变成正逻辑这里也可以换成其他反相方案轻触按键或者拨码开关 16 个10kΩ 上拉电阻 16 个发光二极管 4 个330Ω 到 1kΩ 限流电阻 4 个0.1μF 去耦电容 1 到 2 个5V 稳压电源面包板电源模块或者实验室电源都行面包板若干块杜邦线若干关于 74HC148 的输入有一点特别提醒芯片输入低电平有效但输入引脚不能直接悬空当无效。因为悬空引脚的电平不确定可能因为外界干扰被拉低导致误触发。稳妥的做法是每个输入引脚接一个 10kΩ 上拉电阻到 VCC不按键时输入保持高电平按键按下后接地拉低形成清晰的低电平脉冲。3.2 一步一步搭面包板搭线顺序很重要乱搭容易漏线、错线出了问题还不好查。我建议按下面这个顺序来。第一步先固定芯片位置。两片 74HC148 并排放在面包板中间注意芯片的方向要保持一致缺口朝上引脚 1 在左上角。两个芯片之间留出几列空隙方便走线。74HC00 和 74HC04 放在旁边预留好它们的位置。第二步接电源网络。给每片芯片的 VCC 和 GND 都接好。特别注意 74HC148 的引脚分布VCC 在第 16 脚GND 在第 8 脚。在 VCC 和 GND 之间靠近芯片的位置并联一个 0.1μF 去耦电容这能有效滤除按键抖动瞬间产生的电源毛刺。别小看这个电容我之前在做音频放大器电路图仿真的时候吃过没加去耦电容的亏按键一按LED 亮度都会跟着抖。第三步接输入部分。把 16 个按键的一端分别接到两片 148 的输入引脚另一端接到 GND。每个输入引脚到 VCC 之间接一个上拉电阻。如果没有那么多按键可以先用杜邦线直接接地来模拟有效输入缺点是操作起来不够直观。第四步连接级联线。把高组芯片的 EI 接 GND把高组芯片的 EO 接到低组芯片的 EI。这两根线是整个级联电路的核心建议用不同颜色的杜邦线区分方便排查。第五步连输出合并电路。按照前面的公式把低组和高组的 A2A1A0 分别接进 74HC00 的三个与非门输入端再从输出端引出 Y2Y1Y0。高组的 GS 接进 74HC04 的一个反相器输出端引出 Y3。第六步接 LED 指示。把 Y3Y2Y1Y0 四个输出端各接一个限流电阻然后接 LED 到 GND。这样接线时 LED 亮起来表示该位输出为高比较符合大多数人的阅读习惯。3.3 验证结果哪些组合该出什么码搭建完成之后上电之前先别急把电源电压调到 5V确认无误再通电。我建议先用低组输入测一遍再测高组输入最后测同时输入的情况。单独按下 I0 对应的按键此时 U1 的有效输入是 I0U1 的 A2A1A0 输出为 111经过与非门之后 Y2Y1Y0 为 000Y3 为 0最终四位输出 0000这正好对应 I0 的编号 0。单独按下 I5 对应的按键U1 输出对应的反码 010经过与非门后 Y2Y1Y0 为 101Y3 为 0最终四位输出 0101对应数字 5。单独按下 I12 对应的按键这是高组输入高组芯片检测到 I12输出反码 011经过与非门后 Y2Y1Y0 为 100。高组 GS 为低经过反相器后 Y3 为 1。所以最终输出是 1100对应数字 12。同时按下 I3 和 I10 的按键因为 I10 在高组高组优先级高于低组所以最终输出应该对应 I10也就是 1010。这也是整个电路最有意思的地方你可以亲眼看到优先级链是怎么发挥作用的。可以把这几组测试结果整理成表方便对拍操作Y3Y2Y1Y0十六进制编码无输入00000x0I0 按下00000x0I5 按下01010x5I9 按下10010x9I12 按下11000xCI15 按下11110xFI3 和 I10 同时按下10100xA细心的朋友会发现无输入和有 I0 输入时输出都是 0000。这是低电平有效系统的正常现象因为 I0 是 0 号输入它的原码本来就是 0000。如果系统里需要区分“没有请求”和“0 号请求”可以让低组芯片的 GS 也接出来作为有效标志信号。4. 高频踩坑和排查思路4.1 悬空输入的干扰问题这是最常见的问题没有之一。我之前见过一个同学搭完了电路按键没按LED 偶尔自己亮一下用示波器一挂输入引脚上有乱七八糟的跳变波形。原因就是所有输入引脚悬空CMOS 电路输入阻抗特别高周围环境一点点电磁干扰都能把它拉低。处理办法前面已经说过每个输入引脚加上拉电阻。如果是测试阶段嫌麻烦至少要把当前不用的输入引脚统一接 VCC。特别是当你只测试低组输入时高组的 8 个输入也必须做上拉处理否则高组芯片可能把悬空误判为高组输入从而错误地屏蔽低组芯片。4.2 反码和原码搞混74HC148 输出自带反码这个特性在真值表里写得很清楚但实际操作时特别容易搞混。我推荐一个方法先认准“输出低电平才表示当前位为 1”这个思路。比如 I7 有效芯片输出 000这时候按常识理解7 的二进制是 111两者刚好对应不上。但如果你接上 LED 看I7 对应的应该是 D0、D1、D2 三个 LED 都熄灭。电路我做的是正逻辑输出也就是 Y3Y2Y1Y0 直接对应二进制编号。如果你没有加后面的反相和与非门处理直接从 148 芯片引脚取输出那么拿到的就是反码这一点要特别小心。4.3 两片输出不能直接短接加长线前面讲了要加与非门合并输出但仍然有人偷懒想直接把两片芯片的 A0A1A2 对应短接。短时间测试可能看不出问题因为逻辑电平还没被完全拉坏但只要两组输出状态相反两个推挽输出级就会同时驱动一根线一个拼命往外拉高一个拼命往里灌低电流会在芯片内部持续流动芯片发热量明显上升。这不是我危言耸听。数字电路里最忌讳的就是不同器件争抢一根信号线尤其是同相推挽输出。就算侥幸没烧芯片中间电平也会让后级电路出现逻辑误判。所以务必上与非门合并别省这几颗门电路。4.4 LED 限流电阻千万不要省直接用 LED 去测量 74HC148 的输出LED 本身是二极管正向导通后电阻很小电流可能会达到几十毫安甚至更大。74HC 系列芯片的输出驱动能力并不算强长时间超载会出问题。串一个 330Ω 到 1kΩ 的电阻不仅保护 LED也保护芯片输出级。另外我测过电阻选 1kΩ 时 LED 亮度略暗但完全能看清功耗更小推荐稳妥起见用 1kΩ。4.5 测量时要注意示波器探头接地这算是一个比较容易被忽略的实操细节。测量输出波形时示波器探头地线夹子要尽量靠近芯片引脚不要夹得老远更不要用接地线飞得很长的鳄鱼夹。否则在高频开关状态下测试环路会引入噪声波形看起来就像叠加了振铃。如果只是验证高低电平那用万用表就行但要看按键瞬间的电平跳变还是示波器更直观。我常用 Multisim 先做一遍仿真把按钮抖动和信号时序大概跑一遍再用示波器在实物上验证这样能省不少排查时间。5. 把这个电路往实用方向延伸5.1 十六键键盘扫描直接省掉单片机轮询典型应用是做十六键键盘。普通按键矩阵通常要接成 4×4 阵列然后靠单片机不断扫描行列占用 I/O 口还消耗 CPU 时间。而用 16 线-4 线优先编码器的话16 个按键每个独立接一路输入不用扫描按键按下去时编码器直接输出对应的 4 位编码。这种方案对按键数量的扩展特别方便以后想从 16 键加到 32 键就再加一级 74HC148把输出位扩到 5 位就行代码里只需要读取端口数值不需要写复杂扫描逻辑。唯一要注意的是如果同时按下多个按键输出只代表优先级最高的那个键这跟并行键盘的需求是匹配的。5.2 多路中断优先级仲裁嵌入式系统里经常遇到多个外围设备抢着要 CPU 处理的情况。蜂鸣器响、传感器报警、通信数据到达这些事件不可能同时都被立刻处理总是有轻重缓急。把每个外围设备的中断请求信号反相后接到 74HC148 的输入编码器输出直接连到 MCU 的 GPIOMCU 只需要读一次端口就能知道当前优先级最高的是哪个中断源。而且因为 74HC148 内部自带优先级判定的逻辑多个中断同时到达时MCU 也不会出现优先级判断混乱硬件把这一层工作全承担了。这里有一个实践建议中断请求信号通常不是纯粹的低电平而是一高一低的脉冲。如果直接接 148 输入需要在前面加一级 D 触发器或者锁存器把脉冲锁存成持续的低电平等 MCU 处理完后再清零。否则脉冲太短编码器可能捕捉不到。5.3 并联扩展成 32 线-5 线或者更高如果你觉得 16 路还不够可以继续用同样的思路扩展。第三片芯片处理 I16 到 I23第四片芯片处理 I24 到 I31每增加一个高组输出位就多一位。这种情况下编码输出的最高位变成多个高组的“有没有信号”信号的组合逻辑比两片复杂一些但原理还是建立在 EO 到 EI 级联的基础上。链路级联有一个非常关键的特性需要记住优先级从链尾到链头依次升高离 EI 地端最近的芯片优先级最高。如果你想让某组信号拥有绝对优先权就把那组芯片接到链路的最末端同时把前面所有芯片的 EO 逐级串联到它的 EI 后面。5.4 用仿真软件先练手再动烙铁如果你是刚接触数字电路强烈建议先用 Proteus 或者 Multisim 把电路仿真跑通再动手焊实物。仿真软件里你能直观看到每个引脚的电平状态接线错误时会提示逻辑冲突排查起来比实物快得多。实际建仿真电路时注意把两片 74HC148 的电源和地都正确连接仿真环境下不接电源也不会报错但逻辑结果会完全不对这种问题最容易让人摸不着头脑。另外常见问题是我在实际操作中遇到过的打开仿真软件后找不到 74HC148 这个模型这时可以先到官方元件库里更新索引或者用等价的 74LS148 替代逻辑功能一致跑通原理后再换回 HC 型号。我自己在实际操作中的体会是这种级联类芯片电路最怕的不是画错原理图而是接错地线或者忘记上拉。只要把上拉电阻、去耦电容和级联顺序这三件事做好整个电路一次成功率非常高。你在测试的时候还可以先把高组的 EI 断开接高电平单独验证低组功能再恢复级联这样排查问题会更清晰。希望这篇记录能给你省下一点摸索的时间。