news 2026/9/5 5:51:12

编码器与译码器原理、实战与避坑:从门电路到FPGA和单片机应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
编码器与译码器原理、实战与避坑:从门电路到FPGA和单片机应用

从门电路到系统设计:编码器与译码器的原理、实战与避坑指南

做数字电路设计这几年,我越来越觉得编码器和译码器这俩器件被严重低估了。教科书上它们往往被放在组合逻辑电路那一章,用真值表和逻辑表达式一笔带过,看起来简单到不值一提。但等你真正开始做项目,无论是用74系列芯片搭一个CPU教学模型,还是在FPGA里写地址译码逻辑,甚至是在STM32上配置外设总线,你会发现这俩“基础模块”几乎无处不在,而且是很多疑难杂症的根源所在。

这篇东西我不打算照本宣科地把教材内容复述一遍,而是结合我实际做项目踩过的坑、总结出来的经验,把这俩器件掰开了揉碎了讲清楚。核心内容包括:它们到底在数字系统里扮演什么角色,原理层面的设计思路是怎么回事,以及在实际工程里应该怎么选型、怎么用、出了问题怎么排查。无论是正在学《数字电子技术基础》的学生,还是刚入门嵌入式、FPGA开发的工程师,这篇文章应该都能给你一些课堂和芯片手册之外的东西。

1. 内容整体设计与思路拆解

1.1 为什么编码器和译码器总是成对出现

先看一个最朴素的问题:编码器和译码器为什么总是被放在一起讲?因为它们本质上是一对互逆的操作。译码器把n位二进制码“翻译”成2^n个独立的输出信号,编码器反过来,把2^n个输入信号“压缩”成n位二进制码。一个负责解码,一个负责编码,配合起来就是一组完整的“翻译工具链”。

举一个生活化的例子,你把快递寄回家,快递单上的单号就是一串编码,它把某一单快递的身份压缩成了几位数字和字母;快递员扫描单号,系统通过解码找到这单货该送到哪里。数字系统里,地址线、数据线、控制信号的传递,本质上也是在做这种“编码-传输-解码”的循环。CPU把内存地址通过地址总线送出去,内存芯片上的译码器电路把这个地址翻译成“选中第几行第几列存储单元”的具体操作信号,这才能完成一次读写。

所以我的理解是,编码器和译码器是数字系统里“信息表达”和“信息还原”的两个端点。你在设计任何数字系统时,只要涉及信号的压缩传递或多路选择,就一定跑不掉这俩器件。理解它们成对出现的逻辑,比单独背某一个芯片的引脚功能要重要得多。

1.2 主动学习路线:从真值表到电路实现

很多初学者学习编码器和译码器时,习惯性地“背真值表”,然后做几道化简逻辑表达式的题目,就觉得自己会了。但真到了实际应用环节,就傻眼了:芯片手册上那么多引脚,使能端、扩展端、优先权到底怎么用?实际电路里输出为什么要接上拉电阻?为什么我的译码器在FPGA里综合出来占了好几个LUT?

我的建议是换一条学习路线:先搞清楚“这玩意要解决什么问题”,再去看“用什么结构实现的”,最后才是“真值表长什么样”。翻译成人话就是:

  • 第一步,明确功能需求。比如我有8个设备,想用3根线来区分它们,该怎么做?
  • 第二步,推导逻辑关系。3根线正好能组成2^3=8种状态,每种状态对应一个设备,这就是编码(实际上是优先编码)和译码的数学基础。
  • 第三步,画出电路结构。译码器可以用与门阵列实现,编码器则涉及或门和优先权电路。
  • 第四步,写真值表验证。到这一步你再看真值表,它就是一张验证清单,而不是需要死记硬背的陌生表格。

这个思路放在后续学习数据选择器、加法器、比较器时同样适用。数字电路的知识点看上去零散,实际上全部围绕“如何用有限资源表达和处理信息”这一条主线展开。

2. 核心细节解析与实操要点

2.1 译码器的本质:n线到2^n线的开关矩阵

译码器的核心结构,从逻辑功能上看是一个“与门矩阵”。以3线-8线译码器为例,输入是A2、A1、A0三根地址线,输出是Y0到Y7八根独立的信号线。每一根输出线对应一个特定的输入组合,也就是说,任何一个时刻有且仅有一根输出线被激活(拉低或拉高,取决于芯片是低有效还是高有效)。

你把这8根输出线想象成一个8选1的“铁丝网矩阵”,其中每个交叉点就是一个与门。3根输入线的不同电位组合决定了哪个交叉点导通。74LS138就是这个家族里最经典的成员,它的输出是低电平有效(也就是引脚名上带“非号”的Y0N~Y7N),而且带有3个使能端:G1(高有效)、G2AN和G2BN(低有效)。

这里有一个很关键的实际应用细节:为什么74LS138要设计3个使能端?这不仅仅是为了“能用”或“不能用”。多个使能端的真实价值在于,你可以通过级联让工作时像搭积木一样轻松扩展位数。比如你想用两片74LS138实现一个4线-16线译码器,只需要把最高位地址线A3接第一片的G1,同时通过一个反相器(或与非门)接到第二片的G2AN或G2BN,这样当地址最高位为0时选中第一片,为1时选中第二片,两片交替工作,不会有同时输出的冲突。这个扩展思路,就是多使能端存在的工程意义——它让芯片有了“组合”能力。

2.2 编码器的设计难点:优先级怎么处理

译码器的反向操作就是编码器。8线-3线编码器有8个输入I0~I7,3个输出Y2、Y1、Y0。理论上的功能很直接:当I3为高电平时,输出011;当I5为高电平时,输出101。但这里有个致命问题:如果I3和I5同时有效,输出应该是什么?

实际的数字系统里,多个输入同时有效是常态,而不是异常。比如一个键盘矩阵,用户不可能保证一次只按一个键;一个中断系统,多个外设同时发中断请求太常见了。如果编码器不做任何处理,这种冲突会导致输出混乱,系统行为不可预测。

所以工程上真正用的是“优先编码器”,典型的芯片是74LS148。它的设计思路是:预先给所有输入排一个优先级顺序,当多个输入同时有效时,只对优先级最高的那一个进行编码。74LS148默认I7优先级最高,依次递减,I0最低。这种设计牺牲了一部分“完全编码”能力,换来了系统的确定性——无论输入怎么变化,输出永远是确定的、可预测的。

这里有一个我在实际嵌入式开发中反复体会到的点:数字系统设计里,确定性往往比完备性更重要。你不需要处理所有情况,但你必须把可能遇到的情况都变成确定的行为。优先编码器就是这种设计哲学在芯片层面的直接体现。你在用STM32裸机写中断服务程序时,NVIC的优先级逻辑本质上干的就是这个事。

2.3 使能端和输出极性:最容易忽略的两个细节

再往细了说,做实际项目时有两个点最容易出错:一个是使能端的电平极性搞反,一个是输出极性(高有效还是低有效)没搞清。

先说使能端。74LS138的G1是高有效,需要在高电平时芯片才工作;G2AN和G2BN是低有效,必须为低电平。这个设计在原理上不复杂,但实际画板焊芯片时,如果你把G1误接地、G2A误接VCC,整个芯片就是“死”的,输出永远是无效电平。我见过不少新手拿着万用表量了半天,最后发现是使能端接反了。排查办法也很简单:先用万用表确认使能端的实际电压,再用逻辑笔或示波器看对应输出脚有没有反应。逻辑比猜重要。

再说输出极性。74LS138输出低有效,意味着“选中”的那一路输出是低电平,其他都是高电平。如果你后面接的是高电平有效的外设(比如某个需要高电平触发的继电器驱动),中间就得加反相器,或者直接用74HC238这种高有效版本的芯片。如果你用的是74LS138,却按照高有效逻辑去设计后端电路,结果必然是系统行为完全反转,该开的关着,该关的开着。

在实际项目中,我通常会在原理图里明确标注每一根关键信号线的“有效电平”,并在PCB布局时用不同颜色的网络标签区分。这个习惯看起来很小,但在调试多芯片系统时能省下好几个小时的排查时间。

3. 实操过程与核心环节实现

3.1 用74LS138实现3线-8线译码:从接线到验证

如果你手里有74LS138芯片、面包板、LED和按键开关,完全可以手动搭一个最小译码电路来加深理解。我来梳理整个实操流程,以及每一步我踩过的坑。

3.1.1 硬件准备与接线
  • 74LS138芯片一片(或者74HC138,注意工作电压和驱动能力不同)
  • 5V直流电源(74LS系列一般用5V,74HC系列可以用3.3V~5V)
  • 3个按键开关(用于产生高/低电平输入)
  • 8个LED(用于显示输出状态)
  • 若干电阻(LED限流电阻建议220Ω~470Ω)
  • 面包板和跳线

接线顺序我建议从电源和地开始,先把VCC(16脚)接5V,GND(8脚)接地,然后再接使能端:G1直接接5V,G2AN和G2BN接地。这样芯片从一开始就处于“使能”状态,排除使能端作为变量。

接着接输入:A0接一个按键,通过上拉电阻接VCC(按键按下接地拉低);A1、A2同样操作。这样每个输入都能在0和1之间稳定切换,不会出现悬空导致的逻辑抖动。

最后接输出:Y0~Y7各串一个限流电阻(220Ω比较合适)后接LED负极,LED正极接VCC,这样LED亮就代表该输出为低电平。

3.1.2 测试方法与验证逻辑

测试的时候,先让A2A1A0=000,这时Y0输出低电平,对应LED点亮,其他LED全灭。然后把A0置1,即A2A1A0=001,此时应该是Y1对应的LED点亮。以此类推,全部8种状态都要测一遍,尤其是边界状态:全0和全1时必须且仅有一个LED亮。

这里要特别提醒:千万不要跳着测,比如只测了000和111就下结论说“芯片没问题”。我就遇到过一次,芯片内部某个与门有问题,000和111状态正常,但中间的010和101状态输出错误。这种间歇性缺陷用全量测试能轻松发现,用抽查则可能漏掉。

3.1.3 常见错误与排查
  • LED全灭:先测使能端电压,G1是否为高,G2AN和G2BN是否为低。
  • LED全亮:输出没有正确选中任何一路,或者芯片损坏,依次减小输入端触碰检查。
  • 某一路LED不亮:先换LED,再查对应输出脚到LED之间的连接,最后怀疑芯片内部问题。

3.2 用74LS148实现8线-3线优先编码:理解优先级的作用

接下来试着搭一个优先编码器。74LS148的输入是I0~I7(低有效),输出是A2、A0(低有效编码),还有两个重要的状态输出:GS(有输入信号时有效)和EO(无输入信号时有效)。

接线思路和译码器类似,输入I0~I7各接一个按键,用上拉电阻保持高电平,按键按下接地(也就是“有效”)。输出A2、A1、A0各接一个LED(LED正极接VCC,负极通过电阻接输出脚,低电平亮)。GS和EO也分别接LED做状态指示。

测试的看点在于优先级:同时按下I5和I3,输出应该是I5的编码(因为I5优先级更高)。这一点和普通编码器完全不同,也是面试和考试里特别喜欢考的点。

另外一个容易忽略的细节是:74LS148的输出编码也是低有效。也就是说,当I5被按下(输入低有效),输出应该是I5的反码,需要根据数据手册仔细确认。很多人第一次用的时候按“高有效”思维去读输出,结果发现编码全是反的,这也算是一个典型的“极性坑”。

我在实际操作中建议:先按一个键测试,确认输入输出关系;再同时按两个键测试优先级;最后把所有键都按下去,观察GS和EO的状态变化。这样才能完整验证优先编码器的功能。

3.3 在FPGA中用Verilog实现自定义译码器

除了用74系列芯片搭电路,在实际工程中更常见的是在FPGA或CPLD里用HDL实现译码和编码逻辑。这里我给一个最简的3线-8线译码器Verilog示例,方便你对比“硬件接法”和“代码描述”的差异。

module decoder_3to8 ( input wire [2:0] addr, input wire en, output reg [7:0] y ); always @ (*) begin if (!en) begin y = 8'b1111_1111; // 输出高电平,表示无效 end else begin case (addr) 3'b000: y = 8'b1111_1110; 3'b001: y = 8'b1111_1101; 3'b010: y = 8'b1111_1011; 3'b011: y = 8'b1111_0111; 3'b100: y = 8'b1110_1111; 3'b101: y = 8'b1101_1111; 3'b110: y = 8'b1011_1111; 3'b111: y = 8'b0111_1111; default: y = 8'b1111_1111; endcase end end endmodule

这段代码用的输出也是低有效,和第3.1节里的74LS138保持一致。在FPGA里也能方便地实现优先编码器,最常见的写法是用if-else级联,优先级从上到下递增:

module priority_encoder_8to3 ( input wire [7:0] din, // 1表示有请求 output reg [2:0] dout, output reg valid ); always @ (*) begin valid = 1'b0; dout = 3'b000; if (din[7]) begin dout = 3'd7; valid = 1'b1; end else if (din[6]) begin dout = 3'd6; valid = 1'b1; end else if (din[5]) begin dout = 3'd5; valid = 1'b1; end else if (din[4]) begin dout = 3'd4; valid = 1'b1; end else if (din[3]) begin dout = 3'd3; valid = 1'b1; end else if (din[2]) begin dout = 3'd2; valid = 1'b1; end else if (din[1]) begin dout = 3'd1; valid = 1'b1; end else if (din[0]) begin dout = 3'd0; valid = 1'b1; end end endmodule

在实际的FPGA开发中,这种组合逻辑代码综合出来的电路一般不会太复杂,3线-8线译码器大概占几个LUT和IOB。但如果你在一个大的状态机里到处写case语句,而不注意复用译码逻辑,最后综合出来的面积和时序可能会很糟糕。我的经验是:在设计阶段就把“谁负责译码”想清楚,是放在组合逻辑里直接算,还是用存储器查找表(LUTROM)实现,这两种方式在时序和资源上有明显取舍。

3.4 编码器在单片机与电机测速中的典型应用

说了这么多芯片级的内容,很多读者可能更关心编码器在单片机项目里怎么用。事实上,工程上常说的“编码器”有两个含义:一个是数字逻辑电路里的编码器芯片,另一个是用于角度/位置检测的旋转编码器。后者在电机测速、机器人关节、云台控制等领域是绝对的刚需。

以ST电机测速为例,核心元件就是增量式编码器,它输出两路相位相差90°的方波信号,通常称为A相和B相,部分还有Z相零位脉冲。单片机通过检测A、B两路信号的边沿和电平组合,可以判断电机的旋转方向和转速。这就是所谓“正交解码”或“四倍频技术”。

在STM32上,这个任务可以用片上的定时器编码器接口模式(比如TIM_EncoderMode)直接完成,不需要外部额外的正交解码芯片。你用CubeMX配置TIM2为Encoder Mode,然后读取CNT寄存器就能得到位置增量。有一个细节我提醒一下:STM32的编码器接口支持1倍频、2倍频、4倍频三种模式,4倍频模式下分辨率最高但CNT溢出更快,需要在定时器更新中断里做软件扩展计数,否则位置数据会“跑飞”。

如果是用HAL库模拟I2C去读MT6701这类磁编码器(这也是最近不少人在做的方案),则需要特别注意时序和滤波。磁编码器输出的SPI/I2C数据里往往带有噪声,直接读出来的角度值会抖动,必须做软件滤波,比如滑动平均或一阶低通滤波。我在实际项目中用MT6701配合STM32F103做过一个云台位置环,初始读到的角度抖动大概有±0.3°,滤波后能压到±0.02°,整个闭环效果才勉强能看。这种经验不是书本能给你的,必须在调试台上一点点磨出来。

4. 常见问题与排查技巧实录

4.1 译码器输出“飘忽不定”怎么办

现象:电路看起来没问题,但译码器输出有时候选中Y0,有时候选中Y2,完全没有规律性。

排查思路:先排除芯片自身问题,再检查电源和地,然后用示波器看输入信号的上升沿和下降沿。最常见的原因有两个:一是输入引脚悬空,CMOS输入端悬空时电平不确定,会随机落在逻辑0和逻辑1之间,导致译码结果随机;二是按键消抖没做好,物理按键在按下和释放瞬间会产生几十毫秒的机械抖动,如果这个抖动信号直接送进译码器,输出自然会跟着抖。

解决办法:所有输入引脚必须接上拉或下拉电阻,给输入一个确定的默认电平;按键输入建议加RC硬件消抖或软件消抖。如果你用的是74HC系列芯片,悬空输入的危害比74LS更严重,因为CMOS输入阻抗极高,一点点感应电荷都可能改变电平状态。

4.2 74LS148的输出和预期完全相反

现象:按下I4对应的按键,输出却是3(二进制011),与手册预期不符。

这基本是“极性没搞清”。74LS148的输入和输出均为低有效。当I4被按下,I4为低电平,芯片内部优先编码逻辑给出的“原始编码”是4(100),但输出是低有效,所以A2、A1、A0读出来应该是011。如果你用高有效逻辑去理解,就会觉得是反的。解决方法是:看数据手册时特别注意“Active Low”标注,画原理图时也要在信号名上加非号或小圆圈提醒自己。

这个坑不止出现在74LS148上,几乎所有的“使能控制和状态输出”信号都有类似问题。比如74LS138的GS和EO,一个是“有没有输入”,一个是“有没有有效输入”,逻辑关系也全建立在低有效的语境上。我的经验是:拿到任何一款新芯片,先画一张“有效电平表”,把每一个输入输出引脚的“有效状态”标出来,再开始接线和写代码。

4.3 编码器测速数据跳变,是硬件还是软件问题

现象:STM32编码器模式测速,明明电机匀速转动,读到的速度值却上下跳变,甚至偶尔出现负值。

排查步骤:

  • 先用示波器看A、B两相的波形是否标准,会不会有毛刺、上升沿过缓、相位差不对(正常是90°)。
  • 检查电机驱动是否和编码器共地,地电位差会造成信号抖动。
  • 查看定时器配置是否正确:Encoder Mode的极性、滤波器设置、倍频系数。STM32的定时器输入引脚上可以用内部滤波器,开启数字滤波可以在硬件层面滤掉毛刺。
  • 速度和位置要区分读。测速建议用固定时间窗口内计数差值,而不是直接读瞬时CNT;测位置则需要用32位扩展方式处理溢出。

硬件滤波和软件滤波双管齐下后,数据还是跳变的话,问题很可能出在机械安装上——编码器联轴器松动或偏心,每转一圈会周期性引入误差。这属于机械层面的排查,容易被只盯着代码的工程师忽略。

4.4 常见问题速查表

故障现象可能原因排查与解决
译码器LED全灭使能端电平不对、电源接触不良先量使能端电压,再量VCC/GND
译码器LED全亮输入悬空或芯片损坏输入接上下拉电阻,更换芯片验证
某一输出不响应限流电阻断路、芯片内部对应与门损坏用万用表测通断,逐路排除
编码器输出结果错误输入输出极性理解错误查阅数据手册,确认Active Low/High
同时按下多键时输出冲突使用了非优先编码器替换为74LS148等优先编码器
编码器测速跳变硬件毛刺、程序读法不当开启硬件滤波,用固定时间窗口计数
读MT6701角度值抖动传感器噪声大、磁铁安装偏心软件滑动平均,检查磁铁同轴度

5. 延伸思考:编码器/译码器的更多实战应用与设计哲学

5.1 地址译码:让你一秒看懂计算机是怎么访问内存的

我经常和学生说,学好了译码器,你就等于拿到了打开计算机体系结构大门的钥匙。因为CPU访问内存和外设,靠的就是地址译码。地址总线发出一个地址信号,经过译码器(可能在CPU内部,也可能在主板上北桥/南桥芯片组里),选中对应的存储芯片或外设寄存器。

这个方案里最经典的就是“部分译码”和“全译码”的取舍。部分译码只取地址总线的低位去接存储芯片的地址线,高位不参与译码,或者只参与粗略的片选译码。优点是可以减少译码逻辑,缺点是会产生地址空间重叠(同一个物理位置对应多个地址)。全译码则所有地址线都参与译码,地址唯一,但译码逻辑更复杂。在写嵌入式裸机程序时,经常要处理“地址重叠”的问题,如果你理解译码原理,一眼就能看出为什么访问不同地址时会操作到同一个外设。

再往深了说,FPGA开发里的AXI总线地址映射、PCIe的BAR空间映射、芯片内部外设寄存器地址分配,本质上全部是译码逻辑的应用。一个高性能的地址译码器,需要在面积、时序、路由资源之间做平衡,这在复杂SoC设计里是很考功力的。

5.2 编码器与译码器以外的“同源模块”

编码器和译码器所在的“组合逻辑电路”家族里,还有几个关系密切的模块,理解了它们的共同点,你会对整个数字系统有更通透的认识。

数据选择器(MUX)可以看作一个“反向译码器”——通过选择信号,从多路输入中选一路输出。它的输出表达式里也充满与门和或门,结构和译码器高度相似。在工程里,MUX经常用来实现查找表,替代复杂的逻辑函数,本质也是用“地址选择”替代“逻辑实现”。

三态缓冲器是另一个重要的“使能控制”器件。它表面上看很简单,就是“不通导通”,“高阻态”,但如果没有它,总线冲突就会非常频繁。译码器的多个输出端和多个设备接口之间往往需要三态缓冲隔离,这样才能实现“多设备分时复用同一条数据总线”。实际项目中,微控制器的IO口和多个外设芯片的数据线共享一条总线,就必须靠译码器产生“片选信号”,再配合三态缓冲器,决定哪个设备有权占用总线。

5.3 我的一个设计习惯:先画“选中什么”,再画“怎么算”

最后分享一个个人经验:在做任何包含译码或编码逻辑的数字系统时,不要急着写代码或接线,先画一张“选中关系图”。这张图只关心“什么条件下,哪一路被选中”或者说“什么条件下,哪一位输出有效”,不关心具体门电路和表达式的细节。

这张图帮我避免过很多次头脑混乱。举个例子,一个系统需要8个外设,地址线有16根,我怎么设计片选逻辑?我会先画一张表:

地址范围(十六进制)选中的外设片选信号
0x0000~0x0FFFFlashCS_FLASH
0x1000~0x1FFFSRAMCS_SRAM
0x2000~0x2FFFUARTCS_UART
.........

然后我再去决定每一根片选信号用什么逻辑表达式生成,比如CS_FLASH = !A15 && !A14?还是用译码器芯片,比如74LS138,A15和A14接输入,输出就是4个片选信号。这张表看起来简单,但它帮你把“地址分配”和“译码逻辑”两个层面分离了,调试时也能快速定位问题是出在地址映射表,还是出在硬件译码电路。

6. 一些实操中的心得与建议

6.1 万用表、逻辑笔和示波器的配合

如果你在做的是74系列芯片的硬件调试,一个逻辑笔能帮你快速判断PIN脚状态:高电平、低电平还是脉冲。万用表适合量电压是否正常,但遇到快速翻转的信号就无能为力。示波器是最靠谱的,尤其是双通道以上的型号,可以同时观察A相和B相的相位关系,判断正交解码是否正常。

一个实用的排查习惯:先用万用表量电源和地,确认芯片供电正常;然后用逻辑笔或示波器看使能端是否为有效电平;接着看输入信号是否稳定;最后看输出端。按照“电源-使能-输入-输出”这个顺序排查,效率最高。跳过前面直接测输出,很多情况下会得出“芯片坏了”的错误结论,实际上只是某个前级信号没到位。

6.2 数据手册的阅读方法

很多初学者拿到芯片手册不知道看什么,这里给一个“三步阅读法”:

  1. 看功能框图,理解芯片内部有哪些模块,信号流向是什么。
  2. 看真值表,把每一种输入组合对应的输出行为捋一遍,特别注意高/低有效标注。
  3. 看电气特性表,关注工作电压范围、输入高/低电平阈值、输出驱动能力、传输延迟等参数。

尤其是传输延迟(Propagation Delay),在做高速时序设计时非常关键。译码器的传输延迟会直接影响地址建立时间,如果译码器太慢,后面寄存器的建立时间就不满足,系统就会随机出错。这种问题在低频低速电路里几乎不存在,但时钟频率一拉高或总线宽度一变大,时序余量就会变得非常紧张。这也是为什么FPGA内部综合时经常自动对译码逻辑做时序优化,因为工程师手动搭的74系列译码器链在高速场景下根本达不到要求。

6.3 考试、面试和项目之间的关卡

回到《数字电子技术基础》这本教材,编码器和译码器在考试里通常会考:根据功能要求列真值表、写逻辑表达式、画逻辑图;根据逻辑图分析功能;使用集成芯片完成指定逻辑功能以及级联扩展。这些题目虽然基础,但却是面试和项目实战的“底层能力”。

我之前在面试一些嵌入式岗位候选人时,特别喜欢问一个问题:“如果我要用74LS138做4-16译码器,应该怎么接?”这个问题能快速判断一个人是“背过手册”还是“真正动手搭过电路”。答不出来的人,多半项目经历停留在软件层面;能脱口而出用“A3接G1,A3的反相信号接G2AN”的人,基本都自己动手调试过硬件。

所以我的建议很简单:学编码器和译码器,别只停留在课本习题。花几十块钱买几颗芯片和面包板,亲手搭一搭、测一测,再把同样的逻辑用Verilog写一遍、上板验证一遍。这个过程走完,你对组合逻辑电路的理解会有质的飞跃,以后再遇到地址译码、总线仲裁、外设扩展这些问题,都会觉得“不过如此”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 5:51:10

Python读取Excel性能测试:10万行数据选型实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 5:49:24

CLion中printf重定向:为什么是_write而不是fputc?

1. 为什么这个问题会出现在CLion里先说个实际场景。很多朋友第一次在CLion里做STM32或者其他嵌入式开发时,都会遇到同一个困惑:明明照着别人的教程写了fputc重定向,串口助手就是没有任何输出;换成_write之后,printf 立…

作者头像 李华
网站建设 2026/9/5 5:45:23

MBTI四个字母为什么不能换顺序?从四组偏好读懂类型代码

MBTI结果由四个字母组成,但这些字母不是随意排列的缩写。有人测出INFP后,会问能不能写成NIFP;也有人看到ENFJ和INFJ只差一个字母,就把每个位置当作独立分数。理解固定顺序,才能读懂类型代码表达的四组偏好。 第一个位置…

作者头像 李华
网站建设 2026/9/5 5:40:32

LLVM代码混淆实战:从原理到实现控制流扁平化Pass

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 5:36:51

Unity生存建造游戏开发:从物理系统到建造模块的完整实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华