1 前言
随着出租车行业的发展,对出租车计费器的要求也越来越高。最近几年出租
车行业发展迅速,在全国有几千万家出租车公司。该计价器能实现按时间和里程
综合计算车价,能显示时间、里程、单价、总车价等相关信息显示。
信息社会的现代电子产品,性能越来越高,复杂度越来越大,更新步伐也越
来越快。本设计采用 Verilog HDL 语言来设计实现出租车计费系统,具有良好的
电路行为描述和系统描述的能力,并在语言易读性和层次化、结构化设计方面,
表现了强大的生命力和应用潜力。源程序经 ALTERA 的 Quartus II 9.0 软件调试
优化,通过下载到特定芯片后,可应用于实际的出租车计费系统中。本次课程设
计巩固和运用了所学课程,通过理论联系实际,提高了分析、解决技术实际问题
的独立工作能力,通过对一个出租车计费器的设计,进一步熟悉了数字电路系统
设计、制作与调试的方法和步骤。
2 总体方案设计
2.1 设计要求
设计一个出租车计费器,能按路程计费,具体要求如下:
1、实现计费功能,计费标准:按照行驶里程计费,起步价 6.00 元,并在车
行驶 3km 后按照 1.2/km 计费,车辆停止和暂停时不计费。
2、现场模拟汽车的启动、停止、暂停和换挡等状态。
3、设计数码管动态扫描电路,将车费和路程显示出来,各有两位小数。
4、系统时钟 20MHz
2.2 设计原理
设计该出租车有起动键、停止键、暂停键和档位键。起动键为脉冲触发信号,
当其为一个脉冲时,表示汽车已起动,并根据车速的选择和基本车速发出响应频
率的脉冲(计费脉冲)以此来实现车费和路程的计数,同时车费显示起步价;当
停止键为高电平时,表示汽车熄火,同时停止发出脉冲,此时车费和路程计数清
零;当暂停键为高电平时,表示汽车暂停并停止发出脉冲,此时车费和路程计数
暂停;档位键用于改变车速,不同的档位对应着不同的车速,同时路程计数的速
度也不同。
出租车计费器可分为两大模块,即控制模块和译码显示模块。系统框图如下
所示。控制模块实现了计费和路程的计数,并且通过不同的档位来控制车速。 译
码显示模块实现十进制数到 4 位二进制数的转换,以及车费和路程的显示。
3 具体设计内容
3.1 设计总慨
本出租车计费器采用模块化思想设计,设计顺序为自下向上。首先实现系
统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。
3.2 模块设计 1 启动,暂停
3.3 操作过程记录与分析
3.3.1 对控制模块 taxi 进行仿真后得到的功能仿真结果如图 1 所示,时
序仿真结果如图 2 所示。
图 1 Taxi 控制模块功能仿真
图 2 Taxi 控制模块时序仿真
观察波形可知,当启动键“start”为一个脉冲时,表示汽车己起动,车
费 money 显示起步价 6.00 元,同时路程 distance 随着计费脉冲开始计数;
当停止键 stop 为“1”时,表示汽车已经熄火,车费 money 和路程 distance
均为 0;当暂停键 pause 为“1”时,车费和路程停止计数;当档位键分别取
2 和 3 时,路程的计数逐渐加快,表示车速逐渐加快。
具体实现代码:
module taxi(money,distance,clk,stop,start,pause,speedup);
input clk;
input stop;
input start;
input pause;
input[1:0] speedup;
output[12:0] money;
output[12:0] distance;
reg[12:0] money;
reg[12:0] distance;
reg[12:0] money_reg;
//车费寄存器
reg[12:0] distance_reg;
//路程寄存器
reg[3:0] num;
reg[15:0] dis;
reg d;
//控制车速的计数器
//千米计数器
//千米标志位
always @(posedge clk)
begin
if(stop)
begin
//车停止,路程、车费清零
money_reg<='d0;
distance_reg<='d0;
dis<='d0;
num<='d0;
end
else if(start)
//启动后,起步价 6 元
begin
money_reg<='d600;
distance_reg<='d0;
dis<='d0;
num<='d0;
else
end
begin
if(!start&&!stop&&!pause&&!speedup)
//1 档
begin
if(num=='d9)
begin
num<='d0;
distance_reg<=distance_reg+1;
dis<=dis+1;
end
else
begin
num<=num+1;
end
end
else if(!start&&!stop&&!pause&&speedup=='b01)
//2 档
begin
if(num=='d9)
begin
num<='d0;
distance_reg<=distance_reg+2;
dis<=dis+2;
end
else
begin
num<=num+1;
end
end
else if(!start&&!stop&&!pause&&speedup=='b10)
//3 档
begin
if(num=='d9)
begin
num<='d0;
distance_reg<=distance_reg+5;
dis<=dis+5;
end
else
begin
num<=num+1;
end
end
else if(!start&&!stop&&!pause&&speedup=='b11)
//4 档
begin
distance_reg<=distance_reg+1;
dis<=dis+1;
end
end
if(dis>='d100)
begin
d<='d1;
dis<='d0;
end
else
begin
d<='d0;
end
if(distance_reg >= 'd300) //如果超过 3km,则按 1.2 元/km 计费
begin
if(money_reg <='d2000 && d=='d1)
begin
money_reg <= money_reg + 'd120;
end
else if(money_reg >='d2000 && d=='d1)
begin
money_reg <= money_reg + 'd180;
end
end
//------------当计费超过 20 元时,每 km 加收 50%的车费------------
money <= money_reg;
distance <= distance_reg;
end
endmodule
3.3.2 将扫描数码管的分频系数改小后,对译码显示模块 decoder 的功能仿
真结果如图 3 所示,时序仿真结果如图 4 所示。进行译码的时钟频率必须比
汽车的计费时钟高得多,才能实时显示出车费和路程的变化,这里直接采用
晶振时钟 20MHz 即可。其中 comb1 和 comb2 是采用高频时钟控制的计数器,
当输入车费和路程数据后,此计数器开始计数,直到与车费和路费的数值相
等后才停止,这样就实现了大整数到多位十进制数的转换。comb1_a、comb1_b、
comb1_c、comb1_d 为车费的 4 位十进制数表示;comb2_a、comb2_b、 comb2_c、
comb2_d 为路程的 4 位十进制数表示。可以看出,当输入的车费 money_in 和
路程 distance_in 取不同的值时,用高频计数器转换后均输出对应的 4 位十
进制数。
图 3 Decode 模块功能仿真