ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

编码器与译码器原理详解:从74LS138到STM32编码器模式实战

编码器与译码器原理详解:从74LS138到STM32编码器模式实战 数字电子技术里编码器和译码器是我见过最容易被低估的两块芯片。很多同学学到这里看一眼真值表就说“哦就是查表嘛”然后直接翻过去学触发器。等到做实验、做课程设计要用74LS138给单片机扩一个片选或者用74LS148做键盘编码才发现到处都是坑输出低电平有效反来反去、级联信号接错、按键按一下乱跳好几下甚至两片芯片一接就冒烟。这篇文章就是来陪你把这些坑一个个填上的。这篇内容围绕“编码器与译码器”展开面向三类人正在复习《数字电子技术基础》准备考试或考研的电子/自动化学生刚入门单片机、在地址译码和编码器测速上卡壳的嵌入式初学者以及像我一样经常要回去查带使能端级联逻辑的“老油条”。我会从芯片内部逻辑一路讲到旋转编码器、伺服驱动器和STM32的编码器模式把你在热搜词里看到的各种“编码器”串成一条线。1. 先搞清楚编码器和译码器到底在“编”什么1.1 一个类比编码器和译码器是互为镜像的“翻译官”很多人第一次接触编码器和译码器总把它们当成两种完全独立的器件。其实它们就是一对互为反操作的“翻译官”编码器把人能看懂的“含义”比如按键编号、数字量、状态翻译成机器能处理的二进制代码译码器则反过来把二进制代码还原成某种“含义”比如点亮某一位数码管、选中某一片存储器、给某个外设发送脉冲。我用一个生活化的例子解释过很多遍想象你去一栋酒店需要找房间号。编码器的任务是把“客人住在哪一间”这种自然语言转换成保安能懂的编号译码器的任务是看到编号后准确找到对应的房间并按响门铃。数字电路里编码器输入是一组互斥信号输出是二进制码译码器输入是二进制码输出是一组互斥的选通信号。两者组合在一起就构成了一条从“事件”到“代码”再到“动作”的链路。这个“互逆”关系不仅是考试重点也是工程中排查问题的基本框架。我见过不少同学编码器和译码器分开学都会一旦让它们组合工作就犯迷糊根本原因就是没有把这条链路串起来看。先把“输入是什么、输出是什么、谁在翻译谁”想清楚后面的电路才能谈得上调试。1.2 没有这两种芯片数字系统会怎么样你可能会想不就是多引几根线吗计算机为什么非要把信息编码成二进制再传输算一笔账你就明白了。假如一个系统里有16个按键需要检测如果不编码每一路都要单独接到处理器占用16个IO口用编码器之后只需要4根二进制输出线。至于为什么是4根因为2的4次方等于16这正是二进制对数的威力。译码器这边同样如此。4根地址线最多可以表示0到15十六个地址如果要把这十六个地址分别“点亮”成十六个存储芯片的片选信号就必须用译码器把二进制代码展开成16根独立信号线。换句话说编码器解决的是“数量压缩”的问题译码器解决的是“选路展开”的问题。没有它们数字系统要么引脚爆炸要么布线复杂到没法做PCB。从更深一层看编码器和译码器其实就是“硬件化了的查表过程”。真值表里每一行怎么写硬件上就用门电路把对应的与或逻辑搭起来。这个过程本身没有蕴含什么高深算法但它是你建立“数字电路输入到输出的确定性映射”这一观念最好的起点。1.3 别被同名词带偏电机编码器、音视频编码器和AI自编码器如果你经常在网上搜“编码器”会搜出来一堆看似完全不相关的东西ffmpeg编码器、3D卷积自编码器、磁编码器、伺服电机默认编码器线数、STM32定时器编码器模式……这些确实是“编码器”在不同领域的含义但它们和数字电子技术里讲的组合逻辑编码器并不是一回事我在这里先帮你把词义理清后面才不会互相混淆。数字电路里的编码器/译码器是一种组合逻辑器件输入输出之间是“同时刻、无记忆”的映射关系核心是为了信号压缩与地址展开。电机控制领域的旋转编码器是把机械角度/位置转换成电脉冲或数字量的一种传感器核心是测量位置与速度。音视频压缩领域的编码器是把原始媒体流压缩成H.264、H.265等码流的算法软件核心是数据压缩。深度学习中的自编码器则是一种用于特征提取与重建的神经网络结构核心是学习数据表示。搜索热词里出现的“fiash”这个词虽然写法有些特别但你把它和“ffmpeg”“播放器需要新的编码器”放一起看就知道指的是音视频编解码器而不是数电课本里的74LS148。这篇文章的主体还是讲数字电子技术里的编码器和译码器但在第5章我会专门延伸讲旋转编码器和伺服编码器因为它们和嵌入式工程的关系最紧密也是线上线下被问得最多的话题。2. 编码器原理拆解从硬接线真值表到优先编码2.1 最朴素的编码器就是“一张真值表按引脚连死”先看最简单的情况8线-3线编码器8个输入I0到I73个输出Y2、Y1、Y0高电平有效含义是“当某一个输入为1时输出该输入编号的二进制代码”。比如I4为1时输出1004I6为1时输出1106。这种编码器的设计思路非常直白把真值表抄下来写逻辑表达式再用门电路实现。拿Y2这一路来说只有I4、I5、I6、I7当中任意一个为1时Y2才需要为1因为这四个编号的二进制最高位都是1。所以逻辑表达式就是 Y2 I4 I5 I6 I7。同理Y1 I2 I3 I6 I7Y0 I1 I3 I5 I7。整个电路只需要三个或门组输入直接接进去输出直接接出来没有任何时钟这就是“组合逻辑”。这个设计有一个隐含前提任何时刻最多只有一个输入为1。如果两个输入同时为1输出就会变成一个乱七八糟的“混合码”。实际系统中这种“独热”约束往往并不成立比如两个按键同时被按下于是才有了下面要说的优先编码器。所以我说最朴素的编码器是“理想化”的它帮你理解原理但不适合直接拿到工程里用。2.2 优先级多路同时有效时到底听谁的工程里更实用的是优先编码器典型代表是74LS1488线-3线优先编码器。它和刚才讲的朴素编码器最大的区别在于即使有多个输入同时有效输出也只认优先级最高的那一路。74LS148约定I7优先级最高I0最低所以当I5和I2同时为1时输出对应编号5不会出现“局部或”的乱码。74LS148的输入输出都是低电平有效这背后有工程考虑TTL电路吸收电流的能力比输出电流强信号线悬空时容易被干扰拉成低电平所以很多工业芯片习惯把“有效”定义成低电平利用下拉电阻和“或门”逻辑天然配合。使用这类芯片时必须养成“带反相看真值表”的习惯否则非常容易把输入输出理解反。此外74LS148还有三个“配角”引脚使能输入EI、使能输出EO和优先标志GS。EI1时芯片不工作所有输出为高阻或无效EI0时芯片进入工作状态。当芯片工作但没有有效输入时EO输出低电平GS输出高电平当芯片工作且有输入被编码时EO输出高电平GS输出低电平。这个GS和EO在很多教科书上会被一句话带过但级联时它们就是命根子。2.3 两片74LS148拼成16线-4线编码器实验中经常有把8路编码扩展到16路的需求比如16个按键要编码成4位二进制编号。用两片74LS148就能实现接法非常经典高位片处理I8到I15的EI直接接地让它始终工作高位片的EO接到低位片处理I0到I7的EIOR两片对应的Y0/Y1/Y2输出得到低三位高位片的GS作为输出最高位。这个接法的原理是优先级贯穿高位片的优先级天然高于低位片。只要高位片有任何一路输入GS就变低并完成编码同时EO变高把低位片禁掉低位片的输出作废。只有高位片完全无输入时EO才变低低位片才被允许工作此时用高位片GS输出“0”代表编号落在0到7之间。这样一来16路输入就变成了4位二进制输出优先级顺序也保持了连续性。我在实验课上看到很多人第一次搭这个电路时最常犯的错是把EO接到另一片同样功能的引脚上却忘了用GS做最高位结果输出始终只有0到7。这里给大家一个建议调级联电路时先用“单路测试法”——只接通某一输入比如I13顺着信号查一遍哪一级被禁止、哪一级在编码。只要中间某级偏离了预期立刻就能定位。这个排查方法比我当年拿万用表乱戳半个下午不知道强多少倍。3. 译码器原理拆解74LS138的常用玩法和进阶偷懒技巧3.1 3线-8线译码器内部到底怎么搭出来的74LS138是3线-8线译码器里的“人民代表”。三个输入A、B、C三个使能端G1、G2A、G2B八个低电平有效的输出Y0到Y7。它内部相当于是三输入变量的“最小项发生器”八个与门每个与门对应唯一一种输入组合输出低电平表示该组合被选中。为什么输出要设计成低电平有效因为译码器的主要用途是片选和选通而TTL电路低电平“灌电流”能力强用低电平驱动负载更可靠另外多个译码器输出做“线与”时低电平有效用起来也更符合“有任一选中即拉低”的逻辑。记住这一点后面调片选信号时你会感谢当年记笔记的自己。74LS138的使能逻辑是G1为高同时G2A和G2B都为低芯片才工作并译码否则不管A、B、C是什么所有输出全部为高无效。这个“多使能端”设计不是白给的它让你可以非常方便地做级联扩展。比如要搞4线-16线译码器用两片74LS138第一片的G1接高位地址A3的反相第二片的G1直接接A3A0到A2同时接两片的A、B、C。A30时第一片工作A31时第二片工作16个输出就被展开成两排了。3.2 地址译码与数据分配器单片机外扩的两种典型玩法在实际单片机系统里74LS138最常见的任务是地址译码。比如8086或51单片机要扩展多片存储器或IO接口地址线的高位经过译码后产生各个芯片的片选CS。以51单片机为例P2口的高位地址A15、A14、A13接到74LS138的A、B、C译码输出Y0到Y7分别“管辖”不同的8KB空间。只要程序访问对应地址范围对应片选就会自动拉低硬件上不用CPU管任何事。另一种玩法是当数据分配器Demultiplexer。把G2A当作数据输入端DA、B、C当作选择地址那么D的电平就会“原样传送”到对应的输出端。比如A、B、C011时D会被送到Y3。这就像是一个“单刀八掷开关”常用于在多个外设之间分发同一个数据/控制信号。注意这里的D是高还是低有效取决于你接到哪个使能端接法不同路由输出的极性也不同这是一个容易绕晕的点。当年我帮一个学弟查他做的“八路流水灯”逻辑明明是对的一上电就全灭。后来才发现他把G2A和G2B当成了“或非”逻辑中的两个输入一个接地一个接数据但手册上要求两个都必须是低他给的却是高电平有效的数据。这类错误用万用表很难察觉建议把芯片手册里使能端的表格抄在实验报告第一页调不出来时反复对照。3.3 进阶技巧用译码器当逻辑函数发生器除了做片选和分配74LS138还有一个经常被忽视的本领——当组合逻辑函数发生器。因为译码器每个输出对应一个最小项的反相理论上任何一个三变量逻辑函数都能用它加一个或门/与非门实现。这比用一堆与门或门搭起来简洁得多尤其是在实验板上只剩几个芯片、又不想多插芯片的时候。拿1位全加器举例。全加器有三个输入A、B和低位进位Ci输出是和S与进位Co。真值表展开后S对应最小项编号1、2、4、7Co对应3、5、6、7。如果输入接到74LS138的A、B、C则Y1到Y7分别就是这些最小项的低有效输出。因为Y_i (m_i)非所以S的表达式可以写成 S Y1非 Y2非 Y4非 Y7非取一次反就能得到 Y1·Y2·Y4·Y7 的与非形式。把Y1、Y2、Y4、Y7接到一个四输入与非门输出就是SCo同理接Y3、Y5、Y6、Y7到一个四输入与非门即可。这个技巧在教材上叫“MSI实现组合逻辑”考试爱考工程里偶尔也会救命。核心思想是译码器是“最小项发生器”你有N个变量就找一片2的N次方输出的译码器再配合一个或门/与非门任何这个变量个数以内的逻辑函数都能拼出来。熟练使用这套思路你对“中规模集成电路”的理解会顺势上一个大台阶。4. 从芯片到真实系统七段数码管显示与编码器实战4.1 七段译码驱动芯片为什么说它是“半译码半驱动”如果你做过带数码管的课设一定用过74LS47或74LS48这类芯片。它们输入的是BCD码0-9的二进制编码输出的是七段数码管需要的a到g段信号所以叫BCD-七段译码器/驱动器。和74LS138这种纯译码器相比它除了做逻辑翻译还能直接输出一定的驱动电流所以我说它是“半译码半驱动”。74LS48输出高电平有效适合共阴极数码管74LS47输出低电平有效适合共阳极数码管。用之前一定先确认你的数码管是共阴还是共阳接反了要么全暗要么全亮那种“所有段一起亮但不听控制”的现象基本就是共阴共阳选反了。另外芯片输出端一般都需要串限流电阻阻值取220欧姆到1千欧之间具体看电源电压和数码管压降不会算的优先用1k先试亮再逐渐减小。这类芯片还附带了几个非常有用的控制脚灯测试LT、灭灯输入BI/RBO、灭零输入RBI。LT拉低时所有段强制亮用来检测数码管有没有坏段RBI和RBO配合可以把小数点前或后无意义的“0”熄灭让显示更自然。很多书把这几个脚当作“扩展知识”忽略掉但实际产品面板上那个“数值前面不显示多余0”的效果就是靠它们实现的。4.2 动态扫描显示的时序控制直接让每位数码管都占一组译码驱动电路会很臃肿。所以多位数码管通常采用“动态扫描”所有位的段选线a-g等并联位选线单独控制单片机轮流让某一位点亮利用视觉暂留让肉眼“看到”所有位同时在亮。这本质上是把“静态空间并行”换成了“动态时间复用”用速度换IO口数量。扫描频率要超过人眼的闪烁融合阈值一般每人眼融合频率在50Hz左右实际工程里4位扫描周期做到4到10ms比较稳。如果4位数码管扫描周期是8ms那么每位置就只能亮2ms左右占空比只有1/4。占空比太低会导致亮度明显下降所以动态扫描显示器的段选限流电阻通常要比静态显示取得小一些否则看起来会很暗。写代码时要注意消隐每一位切到下一位置前先把段选全部清零再切换位选否则下一位会短暂显示上一位的残影。这个“先关段再换位再开段”的时序是动态扫描最常见的调试点。很多人显示乱跳第一反应是“硬件虚焊”其实多半是代码里没有消隐。我习惯把这段专门封装成一个函数注释里写清十六字口诀先灭段、再换位、后送码、必消隐。4.3 编码器/译码器在现代FPGA设计中的“还魂”如果你将来接触FPGA或Verilog/VHDL可能会以为74LS138这种中规模芯片已经“退出历史舞台”。实际上恰恰相反编码器和译码器的行为定义已经“融化”成了硬件描述语言里的基本语句。你写一个case语句综合器会自动把它翻译成类似译码器结构的选择逻辑你写一段if-elseif综合器也会自动生成带优先级的编码逻辑——这本质上就是把74LS148内部结构重新描述了一遍。比如你想在FPGA里实现一个3线-8线译码器直接这样写就能得到和74LS138行为几乎一致的功能module decoder3to8 ( input wire [2:0] a, input wire en, output reg [7:0] y ); always (*) begin y 8b11111111; // 默认全无效对应低电平有效 if (en) begin case (a) 3b000 : y 8b11111110; 3b001 : y 8b11111101; 3b010 : y 8b11111011; 3b011 : y 8b11110111; 3b100 : y 8b11101111; 3b101 : y 8b11011111; 3b110 : y 8b10111111; 3b111 : y 8b01111111; default: y 8b11111111; endcase end end endmodule这段代码的重点是默认值先给“全1”再用case覆盖选中路为0正好模拟了74LS138低电平有效、未选中路全部为高的行为。有了这样的映射能力你在纸上推导过的所有使能、级联、最小项技巧在FPGA里依然是有效的底层心智模型。很多初学者直接学RTL发现逻辑“悬”就是因为缺了数电芯片这一层硬件直觉的支撑。5. 跳出芯片看工程旋转编码器、伺服编码器与STM32中的“编码器”5.1 编码器这个词到了电机控制里指的是什么第5章要彻底把话题从“数电课本”拉开因为它已经到了嵌入式工程的实际场景。旋转编码器本质上是一个传感器把电机或机械轴的转角、位置、速度转换成数字脉冲或数字量。它的“编码”方式和74LS148完全不是一个层级的但底层思想有共通之处码盘上的码道、刻线、光电/磁感应单元组合起来就是一张“转角和二进制码”的真值表。增量式旋转编码器输出三路信号A、B、Z。A和B相位相差90度称为正交信号用来判断方向和计数Z每转一圈输出一个脉冲作为绝对零位参考。绝对值编码器则直接输出位置码可以是二进制码、格雷码也可以是串行协议如SSI、BiSS、CANopen里的数据帧。它的优点是断电后位置不丢失不需要“找零”在伺服电机、机器人和数控机床里几乎是标配。如果你在网上搜“磁编码器AS5047P”“双磁编码器测电机位置”“码盘式编码器”都属于旋转编码器的范畴。它们之间只是“用什么方式感知”的区别光电式用码盘挡光磁式用磁铁加霍尔/磁阻传感器但都要解决一个问题——把连续的机械角度离散化成数字量分辨率越高码道越多信号处理越复杂。5.2 正交信号、倍频计数与STM32定时器编码器模式增量式编码器测方向靠的是A、B两路相位关系。假设编码器正转时A超前B反装时B超前A。判断方法在每个边沿查看另一路电平比如A上升沿时若B为低判定为正转若B为高判定为反转。用“边沿状态”组合查表就能实时知道方向和步进。这里有个关键工程点倍频。编码器输出A/B每转各N个脉冲如果只在A的上升沿计数一转发N个脉冲叫1倍频在A的上升沿和下降沿都计数是2倍频A和B的上升沿、下降沿都计数就是4倍频。4倍频后每转计数值变成4N分辨率在数值上提高了4倍。注意这个提升只是“计数细分”不会改变码盘刻线的物理精度所以它提高的是测量分辨率不是绝对精度。STM32的定时器有一个专门的编码器模式就是把定时器的两个输入TI1、TI2接A、B硬件自动完成“哪个边沿该不该计数、该加还是该减”的判断。用STM32CubeMX配置时只需要选一个定时器把模式设为Encoder Mode决定是TI1计数、TI2计数还是TI1TI2都计数再设置预分频和自动重载值就行。代码上初始化和普通PWM捕获几乎一样区别是把计数方向标志位读出来就能得到转向// 假设TIM3已经通过CubeMX配置为Encoder Mode int16_t position; uint8_t direction; position (int16_t)__HAL_TIM_GET_COUNTER(htim3); if (__HAL_TIM_IS_TIM_COUNTING_DOWN(htim3)) { direction 1; // 反转 } else { direction 0; // 正转 }配置方面的坑一般集中在编码器信号没接对TI1/TI2对应的GPIO、定时器重载值小于单圈计数值导致计数溢出、没有开启上拉或下拉导致悬空抖动。切记编码器输出是开漏还是推挽会影响GPIO是否要配置上拉这往往是“明明信号对接了就是计数乱”的元凶。5.3 伺服驱动器中“编码器线数262144”到底能不能改搜索热词里有一条很典型“汇川伺服ms1h4在驱动器里查看到默认编码器线数是262144这个数值可以改吗”但凡你做过伺服电机调试一定会遇到这个问题。先把这个数字拆开看262144正好是2的18次方说明这颗电机配的编码器是18位分辨率也就是单圈能区分262144个位置。它对应的要么是17位增量1位多圈要么是18位绝对值编码器具体以电机铭牌为准。驱动器中显示的“编码器线数”本质上不是你可以随便改的“电子齿轮比”而是编码器硬件本身上报给驱动器的分辨率参数。驱动器只是把这个值读出来用来换算转速和位置。如果你强行去改这一项哪怕只差一个数量级驱动器换算出的实际位置、速度都会完全错乱轻则电机原地抖动自检报错重则运行时飞车报警。很多伺服驱动器在修改编码器相关参数后会强制要求重新上电或重新识别编码器就是这个原因。那“这个数值可以改吗”这个问题正确的理解应该是可以改的是控制侧的电子齿轮比、每转脉冲数设定、分频输出参数而不是编码器物理分辨率。你如果想要“少脉冲跑完整圈”事情应该在驱动器电子齿轮里做而不是编辑编码器线数。我见过有人为了省事直接把线数改成10000结果电机转一下驱动器直接报位置超差折腾半天又改回来纯属白忙一场。关于伺服这类问题我一般建议的处理步骤是先核对电机铭牌上的编码器类型和位数再对照驱动器手册确认参数含义最后用驱动器自带的“编码器识别/初始化”功能重新读取。如果显示值与铭牌不符优先检查编码器线缆、屏蔽层接地和供电电压而不是立刻怀疑软件参数。调试表格见下现象可能原因处理方案驱动器显示编码器线数和铭牌不一致编码器线缆接触不良、型号混淆重新插拔并固定线缆按铭牌重新识别修改线数后电机报位置超差参数含义理解错误恢复默认参数在电子齿轮比处做调整电机上电后自检异响、编码器报警编码器供电异常、屏蔽层未接地检查5V供电单点可靠接地编码器读数随机跳变A/B信号未配上下拉、干扰耦合调整GPIO上下拉缩短线缆加磁环6. 实验中的常见问题与排查技巧从毛刺到级联失效6.1 组合逻辑毛刺为什么难抓要怎么消用示波器抓74LS138的输出有时会看到在输入切换过程中明明应该保持高电平的Y输出上出现一个很窄的低电平脉冲这就是竞争冒险产生的毛刺。原因是A、B、C三条输入线的信号到达译码器内部与门的时间不同有的线先到有的线后到在极短时间里就会出现一个错误的临时状态组合逻辑没有寄存器的“同步”保护所以这个临时状态会直接反应到输出。理论上毛刺可以通过在逻辑表达式里添加冗余项来消除比如利用卡诺图找多余圈合并项但工程里更常用的做法是加选通脉冲或输出端并联一个小电容做滤波。选通脉冲的思路是等输入信号都稳定下来后再打开一个“门”让输出通过这个门通常由时钟信号或控制信号充当相当于把组合逻辑输出“锁存”到稳定的那一段。对低速数字电路来说输出到地并联一个几十到几百皮法的电容也能把高频毛刺平滑掉但上高速时就别这么干会把正常边沿也废掉。抓毛刺用示波器也有技巧。毛刺往往是单次的、极窄的普通自动触发根本逮不住。我习惯把触发模式设成“单次”触发电平设到问题电压附近然后用一根很短的接地弹簧针代替长地线夹减少探针环路引入的高频噪声。如果被测信号是一个周期性的切换过程还可以用“脉宽触发”功能专门抓窄脉冲。总之调试这类问题急不得先把触发通道调好再去怀疑芯片。6.2 级联场景下的“反逻辑”陷阱级联74LS138做4线-16线译码器时最常见的错误是使能端的极性搞反。G1要求高电平有效G2A和G2B要求低电平有效三者是“与”的关系。以A3作为片选高位时第一片需要A30时工作所以要经过反相器接到G1第二片需要A31时工作直接接G1同时G2A和G2B都必须接地。多了一个反相器就多了一次“思维取反”很多人会把第一片的接法漏掉反相器结果A30时两片都不动A31时两片都在抢。还有一种“用输出使能做数据分配器”时的极性陷阱数据D如果接在G2A上而G2A是低有效当D1时芯片被禁能输出Y全部为高D0时芯片使能选中路输出低电平。也就是说你对某一路输出看到的是D的反相信号不是D本身。如果要把D原样送出去要么把D接到G1上并知道高电平有效要么在输出端再做一次反相。很多实验报告上的“分配器结果和理论不一致”根子就在这里。针对级联我给自己定了一条“必查清单”第一步核对每片芯片的EI/使能端初始状态第二步确认输出端反相端子的接法第三步用万用表测每个输出引脚的静态电平第四步单独测每片芯片的功能最后再整体联调。这套顺序虽然慢但能避免“问题在两片芯片之间互相甩锅”的僵局。6.3 按键编码输入抖动、编码不稳定的实战处理给74LS148配按键输入时毛刺不只在输出端出现按键本身就是一个巨大的干扰源。机械按键的簧片在按下和释放瞬间会不断弹跳持续时间从几毫秒到几十毫秒不等。如果你直接把按键接到编码器输入端按一下键盘编码器可能连续输出好几个不同的编码看起来就像是“按键乱跳”。这不是编码器坏了而是输入信号本身脏。硬件上最经典的消抖方案是RC低通滤波器加施密特触发器。按键串联一个小电阻到编码器输入再在输入引脚对地并联一个电容让抖动被积分平滑掉后面用施密特反相器做整形恢复出边沿干净的数字电平。RC时间常数取1ms到10ms之间比较合适太小滤不干净太大会让按键响应变慢。软件上单片机也可以做延时消抖检测到电平变化后延时10到20ms再读一次确认状态一致才认为是有效按下。另外使用74LS148做键盘编码时要习惯把“无有效输入”和“有有效输入”分开处理。无输入时GS为高此时即使有低电平输入也可能是噪声处理逻辑应该忽略这种状态只有GS变低输出编码才可采信。这样配合硬件滤波编码器的稳定性会有质的提升。我记得有次帮学生调四路抢答器每抢一次显示数字就乱跳最后查出是按键供电线上长了加上滤波电容后立马稳了。排干扰这种事看似是小问题实际往往决定一个项目能不能交付。就我个人经验来说把74LS138、74LS148这两块芯片在面包板上亲手搭一次比你对着书背十遍真值表都有用。它们的原理不复杂但里面埋着的低有效逻辑、使能端、级联、最小项思想会在你后面学单片机地址映射、FPGA状态编码、伺服电机控制时反复冒出来。我建议你现在就可以找个实验板做一个小项目八个按键输入经过74LS148编码再通过74LS138译码点亮对应一盏灯最后用数码管把编号显示出来。这个“从按到亮到显示”的小链路跑通一次你会发现数字电路里很多零零碎碎的概念突然就全串起来了。如果是已经在做工程的朋友那就从编码器测速这个角度入手用STM32的定时器编码器模式接一个带ABZ的增量编码器先4倍频测转速再慢慢过渡到伺服驱动器里的编码器参数配置。踩过几次坑之后你会建立起一个很重要的心态任何“编码器”本质上都是把真实世界的信息换一种更高效、更可靠的形式存起来或传出去——弄清楚它输入什么、输出什么、为什么是这个编码规则比记住任何一个芯片型号都重要。
返回列表