简介:面向数字电路课程设计与电子类实验报告的《数电课设四路抢答器的设计》PDF文档,适合电子信息、自动化等专业学生及需要完成抢答器小课题的读者参考。内容围绕四路优先抢答系统展开,涵盖设计目的、总体原理框图、主持人控制与复位逻辑、74LS175四D触发器锁存、74ALS133M反馈封锁、七段数码管译码显示及Multisim仿真验证,并给出真值表、工作过程与调试排错思路,有助于理解优先编码、锁存和显示电路的配合。资源包共1个PDF文件,约856KB,篇幅集中、便于打印批注或按模块查阅;已有104人学习下载。若需从理论推导走向仿真与实物搭建,这份资料可作为课设报告框架和电路分析素材,帮助梳理“先按先锁、后按无效”的关键逻辑,并补充常见故障排查方向。
1. 四路抢答器的设计内核:谁先按下,电路怎么"记住"第一个动作
四个人几乎同时按下按钮,数码管只亮一个数字——这是四路抢答器在课设答辩现场最常见的画面。看起来只是亮灯,背后要解决三件事:谁先到、怎么锁住、锁住之后怎么让人看懂。数字电路课程设计反复出这道题,原因不在电路复杂,而在于它把组合逻辑和时序逻辑的分界线摆得很清楚。
按键进来是组合逻辑,优先级判定、编码、译码全在这一层完成。但"第一个"这个语义属于时序——必须有一个器件在首个有效边沿到来的瞬间把结果冻结,之后再按也改不了它。74LS148 负责优先编码,74LS373 负责锁存保持,CD4511 配合数码管把二进制码变成人能读的数字。三个环节各管一段,任何一段时序没对齐,结果就是乱码或者抢答失效。
下面按 74 系列分立芯片走一遍:芯片怎么选、引脚怎么接、GS 到 LE 的锁存窗口留多少纳秒、双人同按为什么判错、上电后数码管为什么有鬼影。手头有实验箱或面包板的可以直接跟线,没有硬件的也能用 Verilog 把同一套逻辑跑通时序再决定要不要焊。
2. 四路抢答器的芯片选型:从 74LS148 优先编码到 CD4511 译码显示
2.1 74LS148 的优先级方向与四路输入怎么接
74LS148 是 8 线-3 线优先编码器,输入输出都是低有效。它的编号越大优先级越高,也就是 I7 优先级最高、I0 最低。这一点直接决定了抢答器的仲裁规则,不是接线接错了才变成这样,而是芯片内部编码树固化下来的。
四路抢答只需要用到其中四个输入。为了让后面译码出来的数字和选手编号对上,建议把 1 号到 4 号选手分别接到 I1、I2、I3、I4,I0、I5、I6、I7 全部接 VCC 保持无效。
| 选手按键 | 接入引脚 | A2 A1 A0(低有效) | 反相后 BCD | 数码管显示 |
|---|---|---|---|---|
| 1 号 S1 | I1 | 1 1 0 | 0 0 0 1 | 1 |
| 2 号 S2 | I2 | 1 0 1 | 0 0 1 0 | 2 |
| 3 号 S3 | I3 | 1 0 0 | 0 0 1 1 | 3 |
| 4 号 S4 | I4 | 0 1 1 | 0 1 0 0 | 4 |
| 无人按下 | — | 1 1 1 | 0 0 0 0 | 灭 |
提示:这张表里 4 号选手的优先权最高,因为 I4 的编号比 I1 大。如果赛制规定 1 号优先,光靠换接线改不过来——换到 I5~I7 只会让优先级更高,而低编号输入在 74LS148 里天生排后面。真要反过来,得在编码器输出之后再加一级优先级反转逻辑,或者改走 74LS175 那条路线。
74LS148 还有两个控制脚容易忽略。EI(使能输入)必须接地,否则整个芯片不工作;GS 是组信号输出,只要有任意一路输入有效就拉低,正好可以拿来做"有人抢答"的标志位,后面锁存电路的触发就靠它。
2.2 锁存级选 74LS373 还是 74LS175
抢答器最难的地方不是编码,是"第一个"这个语义怎么固化。两种常见做法各有取舍。
| 对比项 | 74LS373 透明锁存器 | 74LS175 四 D 触发器 |
|---|---|---|
| 触发方式 | 电平触发,LE 高透明、下降沿锁存 | 边沿触发,公共 CLK 上升沿 |
| 通道数 | 8 路 | 4 路 |
| 处理双人同按 | 由前级 148 完成仲裁 | 不仲裁,可能锁到多个 1 |
| 接线复杂度 | 需要额外产生 LE 保持信号 | 直接接按钮,接线短 |
| 消抖要求 | 中等 | 高,时钟沿前 D 必须稳定 |
| 适合场景 | 要求严格优先权判定 | 只要求显示单个数字 |
74LS175 那条路看着简单:四个消抖后的按钮接 D0~D3,四个按钮相或产生抢答脉冲接 CLK,第一个上升沿把当时的电平锁住。问题在于它没有优先级,两个人真同时按下去,锁到的就是两个 1,后级要么显示乱码,要么得再加一级优先级电路补回去。
74LS373 这条路多了一层,但胜在 148 已经替我们做完了仲裁。剩下的工作只有一个:怎么产生一个只在第一次抢答时有效、之后一直保持的 LE 信号。因为 373 的 LE 是高电平透明、低电平锁存,所以需要的是一个"第一个 GS 到来时拉低、一直保持到复位"的信号。
2.3 CD4511 与共阴数码管的段限流电阻
显示链路是 373 的 Q0~Q2 经反相后送 CD4511 的 A、B、C,D 端接地。CD4511 内部带锁存和消隐,驱动共阴数码管时输出高电平点亮段,每段串一只限流电阻。
# 段限流电阻估算 VCC = 5.0 # 供电 Vf = 1.8 # 红色 LED 正向压降 VOH = 4.0 # CD4511 拉电流 5mA 时的输出高电平 I_seg = 0.006 # 目标段电流 6mA R = (VOH - Vf) / I_seg # 在 E24 系列里找最接近的标准值 series = [220, 270, 330, 390, 470, 560, 680] R_std = min(series, key=lambda x: abs(x - R)) print(f"计算值 R = {R:.1f} Ω -> 标准值 {R_std} Ω") print(f"实际段电流 {(VOH - Vf) / R_std * 1000:.2f} mA")计算出来约 367Ω,就近取 330Ω 或 390Ω。R_std 取 330Ω 时段电流约 6.7mA,亮度够用又不会把 CD4511 的单脚拉爆。VOH 这个参数要按实际拉电流查手册,别直接用 VCC 减 Vf——TTL 兼容的 CMOS 输出在大电流下会掉一大截,按 5V 直接算出来的电阻会偏小,段电流超标。
CD4511 的三个控制脚也要处理干净:LT(灯测试)和 BI(消隐)都接 VCC,LE(显示锁存)接地。这三个脚悬空会引入干扰,上电后数码管可能随机亮出几段,看着像"锁存失败",其实是控制脚没定死。
3. 四路抢答器的最小系统搭建:从消抖 RC 到 GS-LE 锁存保持电路
3.1 按键消抖:RC 参数和施密特整形的配合
机械按键的抖动持续时间在 1~20ms 之间,不同批次差别很大。消抖不足,一次按下会被 148 当成好几次抢答,锁存电路锁到的可能是抖动过程中的某个中间状态。
| R | C | 时间常数 τ | 可抑制抖动 | 备注 |
|---|---|---|---|---|
| 4.7kΩ | 100nF | 0.47ms | < 1ms | 响应快,多数按键滤不干净 |
| 10kΩ | 100nF | 1ms | < 2ms | 常用起点 |
| 47kΩ | 100nF | 4.7ms | < 10ms | 实验箱首选 |
| 100kΩ | 100nF | 10ms | < 20ms | 边沿变缓,必须配施密特 |
纯 RC 后面直接接 TTL 门有风险。TTL 输入在 1.4V 阈值附近会因为缓慢边沿来回穿越而产生多次翻转,等于没消抖。稳妥做法是 RC 之后接 74LS14 这类施密特触发器,利用它的迟滞回差把缓慢边沿整成干净的单次跳变。如果实验箱上没有 74LS14,也可以用 74LS132(四与非施密特)替代,接线方式一样。
注意:RC 时间常数不是越大越好。τ 取 10ms 时,按键释放后要等大约 30ms 输入才回到高电平,连续抢答的响应会变迟钝。课设场景下 4.7ms 到 10ms 是合适区间。
3.2 GS 到 LE 的锁存保持信号怎么产生
直接拿 GS 接 373 的 LE 会有两个问题。第一,GS 是跟随输入的,所有人都松手之后 GS 回到高电平,373 又变透明,显示的数字会掉回 0;第二,GS 和 A2A1A0 是同一颗芯片出来的,传播延迟接近,LE 下降沿有可能赶在数据稳定之前,锁到旧值。
解决办法是用一颗 74LS74 D 触发器把 GS 转成一个持续低电平的保持信号。
// 74LS74 接线:把 GS 的"第一个下降沿"转成持续低电平 // D (pin 2) -> GND // CLK (pin 3) -> 74LS04 反相后的 /GS // /PR (pin 4) -> 上电复位网络,正常为高 // CLR (pin 1) -> VCC // Q (pin 5) -> 74LS373 的 LE (pin 11) // 时序推导(典型值) t_pd_data = 22e-9 # 148 输入 -> A2A1A0 t_pd_gs = 18e-9 # 148 输入 -> GS t_pd_inv = 12e-9 # 74LS04 反相 t_pd_ff = 25e-9 # 74LS74 CLK -> Q t_su_373 = 20e-9 # 373 在 LE 下降沿前要求的建立时间 t_le = t_pd_gs + t_pd_inv + t_pd_ff # LE 到达时刻 t_data = t_pd_data + t_pd_inv # 数据稳定时刻 margin = t_le - t_data - t_su_373 print(f"LE 到达 {t_le*1e9:.0f} ns, 数据稳定 {t_data*1e9:.0f} ns") print(f"建立余量 {margin*1e9:.0f} ns -> {'通过' if margin > 0 else '不足'}")按典型值跑出来 LE 在 55ns 到达,数据在 34ns 稳定,余量只有 1ns。这在纸面上算通过,实际布线只要多几十皮法的走线电容就可能翻车。工程上的余地做法是在 GS 到反相器之间串一级 RC(1kΩ + 100pF,约 100ns 延迟),把 LE 往后推,余量一下拉到 100ns 以上,代价只是抢答响应慢 0.1 微秒,人根本感觉不到。
如果不想加这颗 74LS74,还有一条化简路线:把 373 的输出反馈回它的 D 输入,让锁存值自己保持自己。不过这要求输出三态控制配合,接线反而更绕,课设场景下不推荐。
3.3 复位网络与上电初始状态
复位要同时做两件事:把 74LS74 的 Q 置回高电平让 LE 透明,以及给 373 一个明确的初始输出。用一颗 10kΩ 上拉电阻加 100nF 电容组成上电复位网络接 74LS74 的 /PR,再并联一个常开按钮接地作为手动复位。
上电瞬间电容相当于短路,/PR 被拉到低电平,Q 被置 1,LE 变高,373 透明,此时如果没人按按钮,148 输出 A2A1A0 = 111,反相后 BCD = 0000,数码管消隐。等电容充电到 VCC 之后 /PR 恢复高电平,Q 保持 1,电路进入待抢答状态。
按下复位按钮时 /PR 再次拉低,Q 回到 1,LE 变高,373 重新变透明——注意这时候如果还有选手按着按钮不放,显示会立刻跳到他。所以复位按钮和抢答按钮的使用顺序有讲究:裁判确认结果之后,先让所有选手松手,再按复位。
4. 四路抢答器调试排错:GS 与 LE 时序、双人同按、显示乱码
4.1 用示波器抓 GS 和 LE 的时序
抢答失效最直接的现场就在这两根线上。把示波器两个通道分别接 74LS148 的 GS(pin 14)和 74LS373 的 LE(pin 11),触发设在 GS 的下降沿,单次捕获。
正常波形应该看到 GS 先下降、LE 随后跟着下降,两者之间有几纳秒到几十纳秒的间隔。如果 LE 先降、GS 后降,说明反相器或触发器那一段延迟比预期小,需要在那条路径上补 RC。如果 LE 根本没动,检查 74LS74 的 CLR 是不是误接到 GND——CLR 是低有效清零,接错会让 Q 永远是 0。
还有一个容易漏的点:74LS373 的 OE(pin 1)必须接地。它低有效,悬空时输出是高阻态,数码管会全灭或者随机亮,看上去像锁存失败,实际是输出没打开。
4.2 双人同按的判定与优先权验证
用 74LS148 做仲裁时,双人同按的结果由芯片内部编码树决定,是确定性的,不会出现"这次 2 号、下次 3 号"的随机情况。验证方法是把所有两两组合都试一遍,看结果是否稳定符合 I 编号大者优先。
| 按下组合 | 期望结果 | 若不符的排查方向 |
|---|---|---|
| S1 + S2 | 显示 2 | 消抖 RC 差异过大,S1 边沿更慢 |
| S2 + S3 | 显示 3 | 检查 I3 引脚是否虚焊 |
| S1 + S4 | 显示 4 | 正常,I4 优先 |
| S1 + S3 + S4 | 显示 4 | 若显示 1 或 3,检查 EI 接地 |
| 四人同按 | 显示 4 | 一致即可,不必纠结 |
真要做到"完全同时按下按编号小者优先",就要用一片 74LS138 或 74LS30 加一级显式优先级判决,把编号小的信号手动抬到 148 的高编号输入上。课设通常不要求到这个粒度,把规则说清楚反而更省事。
注意:手按按钮很难做到真正同时,机械差异通常有几毫秒。测试同按场景时用两根跳线短接到地,比用手按更能说明问题。
4.3 数码管乱码与鬼影的三种成因
数码管显示异常基本可以归到三类。
第一类是段码不对应。CD4511 的输出段码是固定的,a 到 g 对应引脚 9 到 15,接错一根就少一段或者两段短接。上电后用 LT 脚接地做灯测试,应该全亮显示"8",如果有段不亮,问题在数码管或限流电阻,跟逻辑无关。
第二类是鬼影,表现为显示的数字上有另一段微弱发热。这多半是限流电阻没串够或者某几段没串电阻,段电流分布不均。每段都要单独电阻,共用一个电阻的接法在动态扫描场景下才勉强能用,静态显示必须分段串。
第三类是显示跳变。如果抢答锁定之后数字还在偶尔闪一下,说明 373 的 LE 有干扰脉冲进入。在 LE 到地之间并一只 100pF 电容能压掉大部分高频毛刺,同时检查 74LS74 的 Q 到 373 的 LE 这条走线是不是太长、是否靠近时钟源。
用下面的命令可以在动手前先把 Verilog 模型跑一遍,确认优先级和锁存保持逻辑没问题,再去调硬件。
# 编译并运行行为级仿真 iverilog -g2012 -o quiz4.out quiz4.v quiz4_tb.v vvp quiz4.out # 查看波形,重点看 valid 拉高之后 bcd 是否冻结 gtkwave quiz4.vcd &对应的 testbench 覆盖四个场景:单独按 2 号、2 号未松时再按 4 号、全部松开、复位后重新抢答 3 号。
// quiz4_tb.v —— 四路抢答器关键场景验证 `timescale 1ns/1ps module quiz4_tb; reg clk, rst_n; reg [3:0] btn_n; wire [3:0] bcd; wire valid; quiz4 u_dut (.clk(clk), .rst_n(rst_n), .btn_n(btn_n), .bcd(bcd), .valid(valid)); initial clk = 1'b0; always #50 clk = ~clk; // 10MHz initial begin $dumpfile("quiz4.vcd"); $dumpvars(0, quiz4_tb); rst_n = 1'b0; btn_n = 4'b1111; #200; rst_n = 1'b1; #200; btn_n = 4'b1101; #1000; // 仅 S2 按下,bit[1] 低 $display("S2 -> bcd=%0d valid=%b", bcd, valid); btn_n = 4'b0101; #1000; // S2+S4 同按,应保持 2 $display("S2+S4 -> bcd=%0d valid=%b", bcd, valid); btn_n = 4'b1111; #1000; // 全松,锁存不应变化 $display("release -> bcd=%0d valid=%b", bcd, valid); rst_n = 1'b0; #200; rst_n = 1'b1; btn_n = 4'b1011; #1000; // 复位后抢 3 号 $display("reset+S3-> bcd=%0d valid=%b", bcd, valid); $finish; end endmodule第二个场景是关键。有效标志拉高之后,即使后面又有人按下更高优先级的按钮,bcd 也必须停在 2 不动。如果仿真里这一条不通过,说明锁存条件写成了"当前有输入就更新"而不是"只在未锁定时更新",硬件上对应 373 的 LE 没有保持住,会跟着输入抖动。
5. 从四路扩到八路:74LS148 满接与 Verilog 参数化验证
四路抢答器做完之后,把 74LS148 剩下的输入用满是自然的下一步。八路场景下 I0 到 I7 全部接上按钮,A2A1A0 直接给出 0 到 7 的 BCD 码,仍然经 373 锁存、CD4511 译码。唯一变化是数码管显示 0~7,需要在面板上把 0 号位对应到 8 号选手,或者接受这个偏移。
硬件扩展有几个实际约束。八路按钮的消抖网络要占用八组 RC 加施密特通道,一块 74LS14 只有六个施密特,八路需要两颗。373 是八通道器件,四路时只用了 Q0~Q2 三路输出,扩到八路并不增加锁存芯片数量,只用三路编码线这一点没变。真正增加的是复位网络的负载——八路按钮同时按下时,复位按钮要能让所有人松开之后一次性清干净。
逻辑验证部分,把路数做成参数,同一份代码就能覆盖四路和八路两种配置。
// quizN.v —— 参数化抢答仲裁与锁存,N 可取 4 或 8 module quizN #( parameter N = 8 ) ( input wire clk, input wire rst_n, input wire [N-1:0] btn_n, // 低有效抢答按键 output reg [3:0] bcd, // 0 表示无人抢答 output reg valid ); reg [N-1:0] sync0, sync1; // 两级同步,跨时钟域输入先打两拍 always @(posedge clk or negedge rst_n) begin if (!rst_n) {sync0, sync1} <= 0; else {sync0, sync1} <= {sync0, btn_n}; end integer i; reg [3:0] bcd_next; reg valid_next; // 从高位向低位扫描,编号大者优先,与 74LS148 一致 always @(*) begin bcd_next = 4'd0; valid_next = 1'b0; for (i = N-1; i >= 0; i = i - 1) begin if (!sync1[i] && !valid_next) begin bcd_next = i[3:0]; valid_next = 1'b1; end end end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin bcd <= 4'd0; valid <= 1'b0; end else if (!valid) begin bcd <= bcd_next; valid <= valid_next; end end endmodule扫描方向写成从 N-1 递减到 0,和 74LS148 的编号大者优先是一致的。bcd_next 用 i 直接截断到 4 位,八路时最大到 7,不会溢出。valid_next 作为扫描过程中的"已找到"标志,一旦置位后续低位就不再覆盖,这就是优先级链在行为级代码里的自然表达。
验证方法是用一个循环把所有单路按键和两两组合都跑一遍。四路时组合数是 C(4,1)+C(4,2)=10,八路时是 36,写一个自动遍历的 testbench 比手写 36 个场景可靠得多。重点观察三件事:单路按下时 bcd 是否等于该路编号、两路同按时是否稳定为编号大者、松开全部按键后 bcd 和 valid 是否保持不变直到复位。
用 iverilog 跑完整遍历,把每条结果打到终端,和硬件实测的对应关系是一一对应的。这样在面包板上换线之前,逻辑层面就已经确认过了,剩下的问题只可能出在消抖和时序余量上——那两件事示波器看得比仿真清楚。
本文还有配套的精品资源,点击获取