ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

74LS193核心应用:反馈清零/置数实现任意进制计数器与级联实战

74LS193核心应用:反馈清零/置数实现任意进制计数器与级联实战 提到74LS193估计不少学数字逻辑的同学第一反应都是“这芯片看着简单一做任意进制就翻车”。我的看法正相反74LS193恰恰是理解计数器本质最容易的一块芯片它自带异步清零、异步置数、加减双时钟把这些特性用明白任意进制设计基本就通了。这篇文章我会从芯片引脚和真值表讲起重点拆解反馈清零和反馈置数两种设计思路然后用手把手的方式做一台模60秒计数器再补上Verilog仿真验证和常见问题排查。无论你是在赶课程设计还是想搞懂计数器级联的底层逻辑这篇文章都值得看完。1. 先搞懂74LS193引脚、真值表与“任意进制”的底气1.1 一张引脚图看懂74LS193在干什么74LS193是一片4位同步二进制可逆计数器翻译成大白话就是它能从0数到15也能从15数回0而且加法和减法分别由两个时钟引脚控制。芯片有16个引脚核心引脚包括加计数时钟CU、减计数时钟CD、异步清零CLR、异步置数LOAD以及4位预置输入A到D和4位输出QA到QD。此外还有进位输出CO和借位输出BO用于多片级联。引脚的具体编号我就不死记硬背了你拿到数据手册看丝印就行。但你需要记住几个功能上的关键点CU是加计数时钟上升沿触发也就是每个上升沿到来时输出加1CD是减计数时钟同样上升沿触发每个上升沿输出减1CLR是高电平有效的异步清零只要CLR为1输出立刻变成0000不需要等时钟LOAD是低电平有效的异步置数只要LOAD为0输出立刻变成预置端A到D的值。这两个“异步”是74LS193最值钱的地方也是做任意进制的关键。输出QA是最低位QD是最高位。当计数到1111再加1时CO会输出一个低电平脉冲当计数到0000再减1时BO会输出一个低电平脉冲。这两个脉冲在级联时很有用但做模数小于16的计数器时反而容易踩坑后面我会专门讲。1.2 关键特性异步清零和异步预置为什么重要我们平时接触的同步计数器比如74LS161它的清零和置数都要等时钟边沿才生效。74LS193不一样清零和预置跟时钟完全无关信号一到立刻执行。这有点像手动急刹车不需要等发动机转完一圈你踩下去车马上停。异步特性对任意进制设计意味着什么很简单。计数器本来只会在0到15之间循环这是16进制。如果我想让它变成10进制就得在它数到某个状态时“强制踹回0”。借着异步清零和异步预置我们可以在任意状态触发复位从而把计数范围压缩成想要的模数。这个思路正是“任意进制设计”的核心。真值表可以这样记优先级从高到低CLR为1时输出清零优先级最高CLR为0且LOAD为0时输出等于预置值两者都无效时CU上升沿加1、CD上升沿减1。需要注意一点CLR和LOAD都不能悬空。CLR悬空可能被噪声误触发清零LOAD悬空会导致计数器不按正常节奏走。实际接线时CLR接地、LOAD接高电平需要反馈时再接逻辑信号这是最基本的习惯。1.3 为什么用74LS193而不是74160网上搜计数器经常会看到74160、4511、共阴数码管这套组合。74160是同步十进制计数器自带进位输出RCO做十进制计数特别省事所以很多数字钟实验直接选它。那为什么还要写74LS193因为74160只能做10进制或者通过级联做10的整数倍而74LS193是4位二进制可逆计数器通过反馈逻辑可以实现任意模数比如3、5、7、11、13这类非十进制的数也都能做。加上它可以加减双向计数很适合做可逆计数器比如停车场车位计数这种既要加又要减的场景。从学习角度讲74LS193的异步清零和异步置数让你必须去思考“反馈信号怎么产生”“会不会有毛刺”“级联怎么进位”这些恰恰是数字逻辑课程里最想让你掌握的能力。所以实验课上用74LS193做任意进制不是因为它比74160好用而是因为它更能练出真功夫。2. 任意进制设计的两种基本方法反馈清零和反馈置数2.1 反馈清零法把计数器“按回去”反馈清零法的思路很直接设目标模数是M就让计数器正常从0往上数当输出变成M时用组合逻辑检测到这个状态给CLR一个高电平脉冲输出立刻回0。这样有效状态就是0到M-1一共M个。举个例子做一个模12计数器也就是数到11之后回0。12的二进制是1100检测QD和QC同时为1就行用一个2输入与门输出接到CLR。电路逻辑是当QD1且QC1时CLR为高计数器清零。因为计数器是依次递增的0到11这些状态不会出现QD和QC同时为1只有12才会所以不会误触发。有人会问12这个状态不是出现了吗确实会出现但它只维持几十纳秒。CLR是异步的检测到12的瞬间就清零回0所以从人眼和大多数慢速电路的角度看12状态几乎不存在。这个方法最大的优点是电路简单一片74LS08就能搞定。但缺点也很明显反馈清零是靠组合逻辑产生一个很窄的脉冲这个脉冲宽度取决于门电路的传输延迟和芯片的清零响应时间通常是几十纳秒级别。如果后级电路对这个窄脉冲敏感比如你直接拿它去做下一级的时钟大概率会出问题。要消除毛刺可以在清零信号上加一级RC低通滤波比如100欧电阻串100皮法电容到地把窄脉冲吃掉但这样也会让清零动作变慢。更好的办法是改用D触发器把清零信号同步到时钟边沿不过那就要加芯片了。2.2 反馈置数法让计数器“装回去”反馈置数法的思路类似但不是清零而是让计数器在某个状态被“装”回预置值。最常见的是把预置端A到D全部接地当检测到某个状态时让LOAD变低输出回到0。这里必须提醒一个很多教材都没写透的细节74LS193的LOAD是异步的也就是说LOAD一旦变低输出立刻等于预置值根本不等时钟。所以如果你在状态M-1时拉低LOADM-1这个状态很可能只是一个极短的脉冲肉眼根本看不到计数器实际表现变成了跳过M-1。这在某些场景下不能接受。那反馈置数法还有什么用它的真正价值在于配合CO进位输出做“偏移计数”。比如我想做模10可以把预置端D设为6让计数器从6数到15一共10个状态然后CO在15回6时输出一个干净利落的进位脉冲。这个进位脉冲宽度是完整的一个时钟周期用来级联下一级非常稳定。代价是输出一直是6到15不是0到9不能直接接4511显示成十进制需要用额外逻辑转换。所以两种方法的选择取决于你的场景如果只是要一个0到M-1的循环反馈清零法最直观如果你需要稳定的进位输出且不在乎输出偏移反馈置数法更可靠如果既要0到M-1循环又要有干净进位那就得用门控时钟或者D触发器打一拍这部分我在模60实战里会讲。2.3 为什么我不推荐“用一个清零脉冲当下级时钟”这个坑我见过太多人踩了。比如做两位十进制计数器有同学想个位清零的时候正好给十位一个时钟让十位加1于是直接把个位的清零信号接到十位的CU。结果十位要么不走要么乱跳。原因有两点。第一清零信号是几十纳秒的窄脉冲而74LS193对时钟脉宽有最低要求窄脉冲很容易不满足触发条件。第二清零信号发生在M状态而不是M-1到0的稳定边沿。你希望十位在“个位从9变0”的时候加1但9到0的过程如果靠窄脉冲去表达时序上非常不可靠。正确的做法是用门控时钟也就是高一位的时钟等于系统时钟与低一位状态检测信号的与运算。比如个位为9时把1Hz时钟放行给十位十位在这个时钟上升沿加1。这个时钟沿是真实的、稳定的系统时钟沿不是组合逻辑产生的毛刺可靠性高得多。下面模60的设计用的就是这种方法。3. 综合实战两片74LS193搭一个模60秒计数器3.1 方案总览个位模10十位模6级联怎么想秒计数器需要从00数到59然后是60清零回00也就是60进制拆成两位就是十位0到5个位0到9。所以整体规划是第一片74LS193做个位模10第二片做十位模6再用门控时钟把两片串起来。先解决个位模10。74LS193本身是模16要让它在10清零用反馈清零法检测10这个状态10的二进制是1010QD和QB同时为1接一个2输入与门输出到CLR就行。这样个位输出序列是0、1、2、3、4、5、6、7、8、9、10窄脉冲、0。有效状态0到9完整保留10只闪一下。再看十位时钟。不能用个位CO因为CO是15到0时才动作而模10在10就清零了CO根本等不到。方案是检测个位为9的状态把系统1Hz时钟门控给十位十位CU 1Hz时钟 与 个位等于9。当个位等于9时下一个1Hz时钟上升沿让十位加1同时个位从9变成10并迅速清零回0。这个上升沿正好对应个位从9到0的进位时刻十位加的时机非常准确。十位模6也是同理。6的二进制是0110检测QC和QB同时为1反馈清零。十位从5变成6的瞬间被清回0所以十位输出0到5循环。3.2 单元电路反馈清零和门控时钟现在把关键逻辑整理成电路连接。假设1Hz时钟已经由555振荡器或信号发生器提供个位芯片叫U1十位芯片叫U2。U1的CU接1Hz时钟CD接高电平禁止减计数。A到D预置端全部接地。CLR接模10清零信号这个信号由一个2输入与门产生输入接U1的QD和QB输出接U1的CLR。LOAD接高电平不使用置数。另外需要一个2输入与门检测个位等于99的二进制是1001所以QD和QA同时为1这个与门输出就是gate_9信号。U2的CU接门控时钟这个门控时钟就是1Hz时钟与gate_9的与运算需要一个2输入与门。U2的CD接高电平A到D全部接地。CLR接模6清零信号由2输入与门检测QC和QB同时为1。LOAD接高电平。这里有个细节值得解释检测10用QD和QB但二进制10、11、14、15都满足QD和QB都是1。为什么不会误触发因为计数器是逐次加1的在0到10这段范围内只有10同时满足QD和QB为1一旦到10就立刻清零根本走不到11和14、15。检测6同理虽然6、7、14、15都满足QC和QB为1但十位到6立刻清零后面的状态不会出现。这是反馈清零法能成立的前提检测逻辑只在有效状态范围内起作用。如果想把进位信号做得更干净可以用一片74LS74 D触发器把gate_9打一拍得到一个与时钟同步的单周期脉冲再送给十位CU。门控时钟方案在1Hz低速下完全够用但如果你要把频率提到兆赫兹级别门控时钟的毛刺和相位延迟就要认真处理了D触发器同步方案更稳。3.3 显示驱动74LS1934511共阴数码管计数器输出的QA到QD是BCD码不能直接给数码管。最常用的方案是接4511这是一片BCD锁存/七段译码/驱动器输出高电平有效适合共阴数码管。网上常说的74160十进制计数器接4511再接共阴数码管也是这个套路74LS193的输出可以直接替换74160只是要先做好模10和模6反馈。接线时注意QA接4511的A输入QB接BQC接CQD接D顺序别搞反。4511的LE是锁存使能端低电平直通高电平锁存简单用可以接地。BI是消隐端正常使用时接高或悬空别接地否则数码管全灭。LT是灯测试端正常使用时接高。数码管的公共端接GND每个段选引脚和4511输出之间串一个220欧到470欧的限流电阻。如果你手头是共阳数码管要换74LS47千万不能直接接4511否则数字会乱。反馈清零产生的窄脉冲可能让数码管在清零瞬间出现毛刺但由于人眼有视觉暂留根本看不见。如果后面要接单片机或者做高精度测量可以在时钟上升沿后用4511的LE锁存当前值把毛刺屏蔽掉。多数课程设计不需要这一步知道有这回事即可。3.4 接线清单与调试步骤自己搭面包板的话建议按下面这个顺序逐步验证不要一口气全接完再通电。先检查电源5V电源接到面包板电源轨每个74LS193的VCC和GND之间就近接一个0.1uF去耦电容。这个电容别省74LS193在翻转瞬间会产生电流毛刺没有去耦电容很可能导致逻辑乱跳。然后只接U1CU接1Hz时钟A到D接地CLR先接地LOAD接高。此时U1是自由运行的16进制计数器用示波器看QA应该看到0.5Hz方波说明芯片本身在工作。再把模10清零的与门接上观察输出应该在0到9循环。如果显示出现A到F说明反馈清零没生效。确认个位正常后再接gate_9检测和门控时钟把U2接上。U2的CU暂时接一个手动按键或做慢速时钟先看十位是否能0到5循环。全部正常后再恢复1Hz时钟接4511和数码管。调试时最好用信号发生器或555振荡器提供时钟不要用按键直接做时钟源。按键的机械抖动会产生一连串随机脉冲每按一次计数器可能跳好几个数根本不是你的设计问题。非要按键做时钟必须加消抖电路比如RC滤波加施密特触发器或者直接用按键产生一个电平再用时钟采样。4. 用Verilog做设计验证从RTL到仿真波形4.1 为什么建议先仿真再接线面包板接线最大的痛苦是线多、接触不良、芯片烧了都看不出来。我的习惯是先把逻辑写进Verilog做一遍功能仿真确认状态转移和我们预期一致再去动硬件。这样可以把“设计错误”和“接线错误”分开调试效率高很多。即使你不上FPGA用仿真验证这么一个小设计也就十分钟。后面真到了以FPGA或者单片机为主的项目里先仿真后上板同样是最稳的工作方式。4.2 74LS193行为级模型怎么搭写Verilog时不需要把74LS193的门级电路完整建出来只要行为级描述功能就行。下面是一个简化模型用优先级处理异步清零、异步置数和加减计数。module ls193_behavior( input clr, input load_n, input cu, input cd, input [3:0] d, output reg [3:0] q ); always (posedge cu or posedge cd or posedge clr or negedge load_n) begin if (clr) q 4b0000; // 异步清零优先级最高 else if (!load_n) q d; // 异步置数优先级次之 else if (cd) q q - 1b1; // 减计数 else if (cu) q q 1b1; // 加计数 end endmodule这个模型里我把加计数和减计数简化成了优先级判断。实际芯片中CU和CD同时有效的竞争行为比这复杂但对验证模60的核心逻辑足够了。仿真通过之后你还是以74LS193数据手册的时序参数为准这一点要清楚。4.3 模60顶层和testbench按照第3章的电路方案顶层可以这样写U1用反馈清零做模10U2的时钟由1Hz时钟和gate_9门控得到再用反馈清零做模6。module counter_mod60( input wire clk_1hz, input wire rst_n, output wire [3:0] sec_low, output wire [3:0] sec_high ); wire [3:0] q_low, q_high; wire clr_low, clr_high; wire gate_9, u2_cu; assign clr_low (q_low 4d10); // 个位检测10清零 assign gate_9 (q_low 4d9); // 个位为9时开闸 assign u2_cu clk_1hz gate_9; // 门控时钟给十位 assign clr_high (q_high 4d6); // 十位检测6清零 ls193_behavior u_low( .clr (clr_low), .load_n (1b1), .cu (clk_1hz), .cd (1b0), .d (4b0000), .q (q_low) ); ls193_behavior u_high( .clr (clr_high), .load_n (1b1), .cu (u2_cu), .cd (1b0), .d (4b0000), .q (q_high) ); assign sec_low q_low; assign sec_high q_high; endmoduletestbench就简单了产生1Hz时钟跑200个周期观察sec_low和sec_high是不是按00到59循环。timescale 1ns/1ps module tb_counter_mod60; reg clk_1hz; reg rst_n; wire [3:0] sec_low, sec_high; counter_mod60 dut( .clk_1hz(clk_1hz), .rst_n(rst_n), .sec_low(sec_low), .sec_high(sec_high) ); initial begin clk_1hz 0; rst_n 0; #5 rst_n 1; repeat(200) begin #500 clk_1hz 0; #500 clk_1hz 1; end $finish; end endmodule仿真波形里你会看到两类很短的毛刺状态个位在9之后会出现一个极窄的10十位在5之后会出现一个极窄的6。这正是硬件上反馈清零脉冲的体现。如果你的仿真工具把组合逻辑延迟设成0这些窄状态可能小到在波形里看不见这都正常。4.4 FPGA和74LS193方案的差异如果你把这段代码直接放到FPGA上综合我建议改成同步清零风格而不是照搬74LS193的异步反馈。FPGA里面用寄存器做计数器最稳的写法是always (posedge clk or negedge rst_n) begin if (!rst_n) count 0; else if (count 59) count 0; else count count 1; end这种写法没有组合逻辑清零毛刺时序收敛也简单。那为什么74LS193实验还强调异步反馈因为我们要从底层理解“反馈”如何改变计数器模数。理解了74LS193再看FPGA时代为什么普遍改用同步设计你会有更深的认识同步设计规避了异步信号的毛刺和亚稳态问题但底层思想仍然是一回事。5. 常见问题与排查技巧实录5.1 问题速查表我把实际中经常遇到的现象、原因和解决办法整理成一张表方便你卡住的时候快速定位。现象可能原因排查与解决计数器乱跳按一次跑好几个数按键抖动、时钟毛刺用信号发生器或555振荡器做时钟按键需消抖数码管显示A到F模10反馈没生效计数器超过9检查检测10的与门输出是否接到CLRLOAD是否误接地十位不走门控时钟没接对gate_9信号错误用示波器看gate_9是否在个位为9时为高个位到不了9CLR或LOAD被异常电平锁定确认CLR接地、LOAD接高不要悬空芯片发热电源接反、输出短路、负载过重断电检查电源极性和接线输出LED要串电阻清零偶尔无效CLR引脚接触不良或清零脉冲太窄检查面包板接触必要时加D触发器同步清零仿真看不到10和6状态反馈清零的窄状态过于短暂正常现象说明清零逻辑在工作5.2 几个我踩过的坑第一个坑是按键直接做时钟。我当年做数字钟实验用按键手动送脉冲结果计数器忽快忽慢我以为芯片坏了换了一片还是这样。后来才知道是按键触点抖动产生了一连串随机脉冲。后来我改用555做1Hz时钟问题立刻消失。从此我养成了习惯凡是要测时钟的电路先问自己“时钟源干不干净”。第二个坑是把LOAD当普通控制信号用。我在一个模60设计里想让计数器在某个时刻停止计数就把LOAD接到了低电平以为这样能“锁住”。结果74LS193的LOAD是异步置数不是时钟使能LOAD为低时输出一直等于预置端的数据计数器完全瘫痪。后来把LOAD接地问题解决了。这个经验让我记住先查真值表再接线别凭感觉。第三个坑是输出接LED没串电阻。QA直接驱动一个LED结果信号被拉低后面电路逻辑判断出错。74LS193的扇出能力和驱动能力有限用它驱动LED必须串电阻一个LED串330欧到1千欧都行。需要驱动较大电流时加缓冲器或者用三极管驱动别硬扛。第四个坑是面包板接触不良。CLR引脚接触不良时表现为“有时候清零有时候不清零”特别像是逻辑错误。排查方法是用万用表直流档红表笔直接顶在芯片的CLR引脚上黑表笔接地一边按时钟一边看电压变化。如果测量时正常而运行时不正常基本可以肯定是接触问题。5.3 如何快速验证计数器进制对不对如果你手头没有示波器可以用数码管直接看循环范围。接上4511和共阴数码管正常时个位应该是0到9循环十位0到5循环。如果看到A、B、C、D、E、F说明反馈清零失效。如果想看二进制状态可以把QA到QD接4个LED降低时钟频率到1Hz左右手动按一次信号发生器的单次触发观察LED状态变化确认序列是否符合预期。这个方法虽然原始但能帮你把“输出状态”和“预期状态”一个个对上号。特别是排查反馈清零有没有在正确状态动作时这种笨办法往往最有效。最后说点实在的。我第一次独立做模60秒计数器时在“十位不走”这个问题上卡了整整一下午最后发现是gate_9检测信号接错了引脚把QA和QD搞反了。从那以后我明白了一个道理计数器级联设计的核心就一句话想清楚哪个边沿在驱动哪一级再动手接线。你如果能把这个思路刻在脑子里74LS193的任意进制应用就真的通了。后续如果你想继续折腾可以试试用它做模24小时钟、可逆车位计数器或者分频器这些项目都会反复用到这里讲的反馈和级联方法。
返回列表