十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

出租车计费计课程设计:从脉冲计数到Verilog仿真与TTL实现

出租车计费计课程设计:从脉冲计数到Verilog仿真与TTL实现 简介出租车计费计数字电路课程设计文档是一份面向电子信息工程及相关专业学生的完整课设参考围绕行车里程计费、等候时间计费和起步费三部分给出总额不超过99.99元的计费器设计方案内容涵盖设计目的、总体框图、各单元电路详解、整机电路图、心得体会与参考文献等。文档对里程计费电路采用干簧继电器脉冲触发与一百八十进制计数器实现1.80元/km单价等候计费电路以六百进制计数器配合一百五十进制计数器完成每10分钟1.50元计费并借助74LS160、74LS273、74LS48等器件构建计数、锁存和显示链路能帮助读者理解数字电路系统设计与调试的完整流程。资源包仅含1个doc文档体积1.46MB结构紧凑便于直接阅读或对照修改。目前已有325人浏览学习适合正在完成数字电路课程设计、需要设计思路与电路原理参考的学生使用。1. 出租车计费计做课程设计真正要解决的三个问题先给一个反直觉的结论出租车计价器里最难的步骤不是菜单上“几块钱一跳”的算术而是把车辆行驶的物理里程和等待时间同时变成两个互不干扰的数字脉冲序列再送到数码管上刷新。任何计费装置都必须回答三个问题轮子转动时怎么稳定加价停车等红灯时怎么按时间加价乘客上下车触发的按键抖动怎么不加价。数字电路课程设计文档的核心价值就是把这三个问题拆分到计数器、译码器、分频器和动态扫描这几类基础单元上而不是直接用单片机固件把它一笔带过。适合读这篇文章的人有两类一类是正在做课程设计并准备写文档的学生另一类是评审或复核这类设计、想快速判断边界条件和验证流程是否完整的工程师。2. 把计费规则换算成脉冲计数的边界条件2.1 里程计费的本质是脉冲计数不是模拟电压换算出租车计费计标定算法的起点是“一公里产生多少个脉冲”。常见的安装方式是在车轮上固定磁钢用霍尔传感器或干簧管输出方波。假设轮胎周长为 1.8 米车轮每转一圈输出 2 个脉冲那么一公里脉冲数就是N_km 1000 / 1.8 × 2 ≈ 1111这个数并不必须取整。课程设计里更常见的做法是先把传感器拆掉用信号发生器直接给计数器一个可调频率再把主机设定为“每 1000 个脉冲跳一次价”这样整个电路可以用 1 kHz 方波快速验收。真正装到车轮上时再引入校准参数把 1111 修正掉。从数字电路的角度看里程计费不用算任何乘法。显示器每一次跳价对应的是距离计数器累计到某个固定值。这个固定值就是“每跳单位价”对应的脉冲数。比如 2 元一跳每跳需要 100 个脉冲那么每个脉冲代表的价格是 0.02 元。如果把价格设计成“每跳 0.1 元”则跳价阈值变为 50 个脉冲。这里要注意仪表显示位数有限建议先用模拟信号发生器把“每跳 0.1 元”调通再在文档里写清楚真实计价系数的换算关系。2.2 起步价、里程价和等待价为什么要走两个独立计数器起步价在课程设计里通常不是“起步后自动叠加”而是通过置数端预置到 BCD 计数器中。常见做法是把 8.00 元拆成 800预置到三位 BCD 加法器的初始值里。里程脉冲到来时加法器每跳到某个进位阈值就加一次费用。预置操作可以用一个按键控制计数器的置数引脚而不是在输入脉冲上做减法。里程和等待必须分开计数。原因很简单车辆低速蠕行时里程脉冲可能还在一路断续到来同时时间计费也仍在累计。如果设计成“里程计数和等待计数共用一个计数器”计价结果会严重失真。正确结构是里程脉冲计数器与等待时间计数器完全并行各自独立累计各自的阈值最终都向同一个 BCD 金额寄存器累加。学习文档时经常会出现一个误区把“等待”信号当成里程计数器的使能。比如乘客上车后按下等待键就把里程计数停掉只用定时器计时。这个设计在真实计费规则里不完全对因为车在绿灯起步瞬间也会输出脉冲。稳妥的写法是计费项目输入信号每跳阈值计数方向起步价空车/重车开关置数预置预置到金额寄存器里程价霍尔脉冲按每跳金额换算加法计数等待价1 Hz 时基按等待计费规则换算加法计数两个计数器并行工作显示端通过多路选择器读取金额寄存器三者之间不存在等待关系。2.3 分频系数要和最大车速一起验算如果等待计时用 1 秒时基时基的来源可以是晶振加 CD4060 分频也可以用 NE555 做自激多谐振荡器。NE555 的频率公式是f ≈ 1.44 / ((R1 2×R2) × C)取 R110kΩ、R268kΩ、C0.1μF频率大约是 98 Hz想得到 1 Hz 还要接一个分频器。晶振方案更可控32768 Hz 经过 15 级二分频后输出 1 Hz误差主要来自晶振本身基本不需要调电容。但这里有一个容易被熟手忽略的约束里程脉冲去抖宽度不能只看机械开关还要按最高车速反推脉冲最小间隔。假设轮胎每转输出 4 个脉冲最高车速 120 km/h 对应车轮转速约 16.7 rps脉冲间隔约为 15 ms。如果去抖单稳态把脉宽设成 22 ms高速状态下每个有效脉冲都会被吞掉。计费计单独跑静态测试没问题装在车上一跑高速就少计费问题几乎都出在这里。车速 km/h轮速 rps4 脉冲/转的最小间隔 ms405.6458011.122.512016.715所以去抖参数不是照抄芯片手册的例程而是先写出这条“最大车速对应最小脉冲间隔”的约束再回选 RC 常数。3. 用 Verilog 搭一个可仿真的计费计数核心3.1 核心模块的端口与参数设计用 Verilog 做数字电路课程设计时我一般会先搭一个纯仿真可用的核心模块把计费规则参数化再用 testbench 快速观察波形。参数不写死是后面写文档时最好解释的部分。// 出租车计费计核心里程脉冲 等待时间 - BCD 金额 module taxi_meter_core #( parameter PULSE_PER_JUMP 100, // 每 100 个里程脉冲跳一次计价单位 parameter WAIT_PER_JUMP 30, // 等待模式下每 30 个时基跳一次 parameter SCAN_PERIOD 500 // 显示扫描计数决定动态刷新频率 )( input wire clk, input wire rst_n, input wire wait_key, // 等待/缓行档位高电平有效 input wire dist_pulse, // 整形滤波后的里程脉冲 output wire [3:0] bit_sel, // 数码管位选 output wire [6:0] seg // 七段码输出 ); // 上升沿检测保证一个脉冲只触发一次计数 reg pulse_d; always (posedge clk or negedge rst_n) begin if (!rst_n) pulse_d 1b0; else pulse_d dist_pulse; end wire pulse_rise dist_pulse !pulse_d; reg [9:0] dist_cnt; reg [4:0] wait_cnt; reg [15:0] fare_bcd; // BCD 金额高 8 位存角/元低 8 位存储分位 reg [9:0] scan_cnt; reg [1:0] scan_pos; always (posedge clk or negedge rst_n) begin if (!rst_n) begin dist_cnt 0; wait_cnt 0; fare_bcd 16h0800; // 起步价预置 8.00 end else begin if (pulse_rise) begin dist_cnt dist_cnt 1; if (dist_cnt PULSE_PER_JUMP - 1) begin dist_cnt 0; // 金额低位 BCD 加 1满 9 进位到高位 if (fare_bcd[3:0] 4h9) fare_bcd[3:0] fare_bcd[3:0] 1; else begin fare_bcd[3:0] 0; fare_bcd[7:4] fare_bcd[7:4] 1; end end end if (wait_key) begin wait_cnt wait_cnt 1; if (wait_cnt WAIT_PER_JUMP - 1) begin wait_cnt 0; // 等待计费的加法逻辑与里程相同 // 完整设计中应封装成进位函数避免重复写 end end end end模块里的 PULSE_PER_JUMP 是计费规则中最关键的可调参数。仿真时把它改成 4 或 10用少量脉冲就能观察到跳价行为实际装车时改成按轮胎周长计算出的真实脉冲数。等待计费的 WAIT_PER_JUMP 是“多少个秒脉冲跳一次”它不直接等于等待秒数而是和时基频率联动。如果时基不是 1 Hz而是 100 Hz那么这个参数要相应放大。3.2 BCD 进位和七段译码不要放在同一个进程里BCD 金额寄存器适合用单独的 always 块维护七段译码用组合逻辑实现。很多人喜欢把金额相加和显示扫描写在一个进程里结果仿真时发现进位和消隐互相干扰。实际做法是拆成三块一是计数与金额累加二是动态扫描位选三是七段译码。// 动态扫描每 SCAN_PERIOD 个时钟切换一次显示位 always (posedge clk or negedge rst_n) begin if (!rst_n) begin scan_cnt 0; scan_pos 0; end else begin scan_cnt scan_cnt 1; if (scan_cnt SCAN_PERIOD - 1) begin scan_cnt 0; scan_pos scan_pos 1; end end end reg [3:0] cur_digit; always (*) begin case (scan_pos) 2d0: cur_digit fare_bcd[3:0]; 2d1: cur_digit fare_bcd[7:4]; 2d2: cur_digit fare_bcd[11:8]; default: cur_digit 4hF; // 最高位暂时熄灭 endcase end位选信号 bit_sel 接的是 74HC138 一类译码器或者直接接三极管的基极。显示频率要避开人眼闪烁频率但也别太高否则三极管开关损耗和电源纹波会变大。扫描周期取 1 kHz 左右比较合适也就是每个位每秒刷新 250 次左右。参数 SCAN_PERIOD 要按主时钟频率换算比如主时钟 50 MHz 时SCAN_PERIOD 取 50000 才能得到 1 kHz 扫描。七段译码表推荐直接用 case 写不要用 if-else 串。以共阴极数码管为例段码 a 到 g 的顺序从 bit0 到 bit6数字 0 到 9 的常用段码依次是00x3F10x0620x5B30x4F40x6650x6D60x7D70x0780x7F90x6F。如果电路里用的是共阳数码管取反即可。组合逻辑里不要出现锁存器case 语句一定要写 default否则综合工具会给你补一个不想要的 latch。3.3 用最小 testbench 验证跳价阈值写 testbench 时不一定要把真实速度模型仿真出来。课程设计文档里最实用的验证方法是把 PULSE_PER_JUMP 覆写成一个很小的值比如 4然后手动产生 4 个脉冲观察金额是否正好增加一次。module tb_taxi_meter_core; reg clk 1b0; reg rst_n 1b0; reg wait_key 1b0; reg dist_pulse 1b0; wire [3:0] bit_sel; wire [6:0] seg; taxi_meter_core #( .PULSE_PER_JUMP(4), .WAIT_PER_JUMP(3) ) dut ( .clk(clk), .rst_n(rst_n), .wait_key(wait_key), .dist_pulse(dist_pulse), .bit_sel(bit_sel), .seg(seg) ); always #10 clk ~clk; // 20ns 周期典型 50MHz 时钟 initial begin #40 rst_n 1b1; // 产生连续 20 个里程脉冲每个脉冲宽度 2 个时钟周期 repeat (20) begin (posedge clk); dist_pulse 1b1; (posedge clk); (posedge clk); dist_pulse 1b0; (posedge clk); end // 拉高等待档位观察等待计数是否按阈值跳价 wait_key 1b1; #2000; wait_key 1b0; #1000; $finish; end endmodule仿真时要在波形窗口里同时观察 dist_cnt、wait_cnt、fare_bcd 三个信号。里程脉冲传入后dist_cnt 应逐周期递增达到阈值时fare_bcd 的低四位加 1 并回零。如果金额一次跳了两位数说明 BCD 进位不完整。还有一种常见错误是 dist_pulse 持续为高电平时同一个脉冲被反复计数这就要回到上升沿检测信号 pulse_rise 上检查。4. 从仿真落到 TTL 芯片的拼搭与排错4.1 典型芯片选型与接线要点如果课程设计要求用 74 系列 TTL 或 4000 系列 CMOS 芯片在面包板上搭最常用的一组器件是CD4060 做晶振分频CD4510 做 BCD 十进制加减计数器CD4511 做 BCD 到七段锁存译码74HC138 做位选扫描。需要说明的是CD4510 是加法计数出租车的起步价预置可以用它的置数端完成不用额外设计减法器。模块推荐器件接线要点秒时基CD4060 32768Hz 晶振晶振接 OSC_IN分频输出接到计数时钟里程去抖整形74HC14 施密特反相器输入先过 RC 低通再进施密特反相器等待计数CD4510 或 CD4020秒脉冲接时钟溢出进位作为跳价标志BCD 译码CD4511段输出接限流电阻到数码管注意 LT、BL、LE 引脚位选驱动74HC138 PNP 三极管138 的 Y 输出控制三极管基极再接到公共端CD4511 的 LE 端要接低电平让它随时刷新LT 端接高平避免测试模式把待显示内容拉灭。前导零的消隐可以靠控制位选来实现而不是在 CD4511 上做复杂逻辑因为 CD4511 的 RBI 和 RBO 只在多片级联时才需要仔细处理。4.2 去抖参数按轮速反向设置机械开关和霍尔传感器输出的波形差别很大。干簧管在磁钢靠近时会有 10 ms 量级的机械抖动直接接计数器会出现一次闭合算好几次的问题。常见做法是先做 RC 低通再接施密特触发器整形。RC 时间常数选 1 ms 左右既能滤掉细窄毛刺又不会严重拖慢最高车速时的脉冲。不要看到芯片手册的单稳态电路就照抄。单稳态宽度公式是 T1.1RC比如 R20kΩ、C1μF 时 T22ms这个宽度在静态测试中看起来很完美但代入 120 km/h 的脉冲间隔 15ms 后会发现每个脉冲还没结束就被单稳态复位计数器直接丢脉冲。比较实用的计算路径是先确定传感器每转脉冲数再算出最高车速对应的最短间隔最后把单稳态宽度设成最短间隔的三分之一以内。课程设计文档里能写出这一步推导比贴再多样例都有说服力。4.3 面包板走线和电源旁路的常见陷阱多个计数芯片共用时钟时连接线要尽量短且每两个芯片之间避免跨过太长并排的电源线。TTL 芯片的扇出能力有限一个 74HC 系列反相器可以直接驱动同系列计数器的时钟端但要驱动四个 CD4511 就不行需要通过缓冲器或三极管扩流。电源端的去耦电容每片芯片都加 0.1μF靠近电源引脚放置如果面板上还有数码管动态扫描总线上会有较大纹波建议再加一个 100μF 电解电容。排错顺序也有讲究。先断开数码管用示波器看计数时钟是否有上升沿再用手动按键逐个送入脉冲确认 CD4510 的 Q 输出按 BCD 码变化最后再接 CD4511。不要把示波器探头直接夹在晶振输出端来验证分频结果探头电容会改变振荡频率。正确做法是量 CD4060 的 Q14 引脚看到稳定的方波后再向下游查。5. 标定、回环测试和一张能签字的验收表5.1 转圈法和示波器测速结合实际装轮标定时人工数脉冲是最可靠的参照。把车轮悬空在轮毂上一个固定位置贴反光标记每转一圈都间隔性地确认。转动 50 圈后用示波器数出传感器输出的脉冲总数再除以圈数得到每转脉冲数。这个数乘以轮胎周长才是计费计真正使用的“每公里脉冲数”。只按霍尔手册标的“每转两个脉冲”直接写参数会因为磁钢距离和安装偏心产生明显误差。示波器测量时用上升沿触发把时基调到能看到相邻两个脉冲间隔即可。记录脉冲间隔后用 1 除以间隔得到当前轮速再根据轮胎周长换算成车速。这一项数据同时用来校验去抖宽度是否合理也是验收表里的关键原始记录。5.2 用信号发生器做回环测试回环测试是把里程脉冲改成信号发生器的方波输出频率从 1 Hz 到 1 kHz 连续可调。信号发生器输出阻抗通常为 50Ω接到 TTL 电路时要先串一个 1kΩ 电阻限流避免负电平损坏 CMOS 输入。频率设成 100 Hz持续发送 100 秒总计 10000 个脉冲。如果计费计设定的每跳阈值为 100最终显示金额应增加 100 个计价单位偏差不超过 1。这个测试不能用“看一眼跳动正常”来验收一定要记录开始和结束金额。等待计费部分用同样方法把秒时基接到计数器持续运行 5 分钟对比最终跳动次数和理论值。回环测试把传感器、机械安装、计费逻辑三者分开定位问题时会很省时间。5.3 验收表至少要有四列原始数据课程设计文档最后附一张表比一大段文字描述更有用。表里必须包含四列测试动作、输入脉冲数或等待秒数、显示期望值、实测值。遇到偏差时再加一列“误差原因”不要直接在原数据上修改。序号测试动作输入条件期望显示实测显示1上电复位置数端动作8.008.032里程 100 脉冲PULSE_PER_JUMP1008.018.013等待 30 秒WAIT_PER_JUMP308.028.024连续 10000 脉冲1 kHz 方波9.009.01填表时注意一个额外参数晶振实际频率并不等于标称频率用示波器数出每秒脉冲后回填到分频系数表里就会多出一列“频率修正量”。把修正量和显示器实测值放在一起课程设计的验收才算真正覆盖了数字电路里的时序问题。本文还有配套的精品资源点击获取
返回列表