随着现代社会的不断发展,出租车逐渐融入生活,成为人们外出的普遍选择方式,对于出租车而言,人为的计算价格容易产生误差,这时候拥有一个良好的计费系统是必要的,不仅能够解决出租车司机计算价格的麻烦,同时也能使金额计算通透,便于乘客了解价格的合理性。
本课题是基于Cyclone II:EP2C8Q208C8芯片,完成了出租车计费的功能。课题主要包括几个模块,分别是分频模块、控制模块、时间模块、计费模块和显示模块。
经过实验证明,本设计能实现出租车计费
系统方案的设计
根据整个系统的设计要求可知,整个系统中的信号有:系统内部时钟信号,按键控制信号。
图2-2: 出租车计费系统结构图
本系统应该能实现的功能:正常完成出租车实时计费,等待时间计费,最终价格显示的功能。出租车计费系统的结构简图如图2-2所示。
程序设计及仿真
3.1 分频器模块
3.1.1 分频器模块程序设计
时钟对于整个系统而言是非常重要的,系统内部的时钟是50MHz,对于本设计而言,频率较高,须将其进行分频处理后,才能得到想要的频率。
其程序关键部分及注释如下:
module div(clk,rst,f0,f1);
//两个频率出去,f0:到下一个单元模拟车辆行驶
//f1模拟电子时钟
input clk,rst;
output reg f0,f1;
reg [18:0]count1;
reg [18:0]count2;
always@ (posedge clk or negedge rst)
begin
if(!rst)
begin
count2<=0;
count1<=0;
f0<=0;
f1<=0;
end
else
begin
if(count1<1999_99)
begin
count1 <= count1 + 1'b1;
end
else
begin
count1<=0;
f0=!f0;
end
if(count2<499_999)
begin
count2 <= count2 + 1'b1;
end
else
begin
count2<=0;
f1=!f1;
end
end
end
endmodule
由程序分析可知:
系统内部时钟传入一个50MHz的频率,经过两次分频后,分别得到f0,f1两个频率,为了方便演示,对等待时间经过处理, 提高了显示时间所对应的频率。
f0,f1初始时设置为0,通过计数器计数后,将其翻转,从而得到想要的频率。
3.1.2 仿真结果
根据上面的程序,利用EDA软件Quartus II进行仿真,分频器模块的功能仿真如图4-1所示。
图4-1:分频器模块仿真结果
由仿真图可知:
clk表示系统内部时钟,通过不同的计数方式输出两个频率。
f0用于模拟汽车行驶,没出现一个高电平,表示出现一个脉冲。
f1用于表示等待时间的频率。
3.2 抢答计时模块
3.2.1 控制模块程序设计
控制模块输入有三个按键信号key1,key2,rst;一个时钟信号clk_1,一个输出,mil表示汽车行驶路程。本次设计中,司机开始启动汽车进行行驶,即为key1按下,控制汽车的行驶路程,最后传输给计费模块和寄存器,寄存器处理数据后在传给显示模块,进行路程显示;当司机停止行驶,进入等待时间,即key2按下,在计时模块中,同时控制着时间的计算。
代码如下:
module control(key1,key2,rst,clk_1,mil);
input key1,key2,rst;
input clk_1;
output reg [9:0]mil;
reg [16:0]Q1;
reg [1:0]X;
always@ (posedge clk_1 or negedge rst)
begin
if(rst==0)
begin
Q1<=0;
end
else
begin
if(key1)
begin
if(mil<999)
begin
Q1<=Q1+X;
mil<=Q1/100;
if(key2)X<=0;
else X<=2;
end
end
end
end
endmodule
由程序分析可知:
检测时钟信号clk_1的上升沿和复位信号rst的下降沿,当rst为0时中间变量Q1置0,如果rst不为0,就检测按键key1,key1按键按下后,开始计算行驶路程,最大值不超过999,当按键ksy2按下后,会将计数器保持为原值,不会进行加数计算,输出值mil及为行驶路程。
3.2.2 仿真结果
根据上面的程序,利用EDA软件Quartus II进行仿真,控制模块的功能仿真如图4-2所示。
图4-2:控制模块仿真结果
由仿真图可知:
检测输入信号clk_1,按键rst ,key1均为1时,开始计算里程,当rst为0时,里程计数清零,当key2为1时,里程数停止计算。
3.3 计时模块
3.3.1 计时模块程序设计
计时模块分别有三个输入信号,一个输出信号,clk_2代表的是分频器输入的信号,key2用于控制等待时间的计算,控制频率,rst用于清除等待时间,Q表示输出的等待时间。当司机因为交通等原因不得不进行等待时,key2键按下,此时汽车停止行驶,但开始计时,输出为分钟,分钟会参与到计费模块和寄存器模块,最终显示在数码管上。
设计程序如下:
module clock(clk_2,key2,rst,Q);
input clk_2,rst,key2;
output reg [5:0]Q;
reg [5:0]s;
reg clk_t;
always@( clk_2 or rst)
begin
if(rst==0)
begin
clk_t<=0;
end
else
begin
if(key2)clk_t<=clk_2;
else clk_t<=0;
end
end
always@ (posedge clk_t or negedge rst)
begin
if(rst==0)
begin
s<=0;
Q<=0;
end
else
begin
if(Q<60)
begin
if(s<60)
begin
s<=s+1;
end
else
begin
s<=0;
Q<=Q+1;
end
end
else Q<=0;
end
end
endmodule
由程序分析可得:
程序对输入信号clk_2,rst进行检测,中间变量为clk_t,作用为传输计时用的频率,当按键rst为0时,clk_t为0,rst为1时,将对应的输入 信号clk_2传输给clk_t;下一步检测clk_t的上升沿和rst的下降沿,rst为0,分钟和秒数均置0,当为1时,先进行秒数加1,当秒数为60时,置0,分钟数加一,最大值不超过60分钟。
3.3.2 仿真结果
根据上面的程序,利用EDA软件Quartus II进行仿真,计时模块模块的功能仿真如图4-3所示。
图4-3:计时模块仿真结果
由仿真图可知:
当输入信号输入的时候,key2置1时开始计时,当rst为0时,计时清零,此时计数器重新计时。
3.4 计费模块
3.4.1 计费模块程序设计
计费模块主要进行金额的计算,此模块有一个里程信号Mil输入,一个等待时间Q,一个内部时钟和清零信号输入,最终输出金额A。当rst为高电平时,根据输入信号Q来判断进行工作,由于价格会和等待时间相关,在小于3分钟时,等待时间不会产生计费,大于3分钟后每分钟多1元;再判断行驶路程,当小于3公里,则是10元,当大于3公里后,每公里又会是2元每公里;还有一个情况就是当总金额大于50元时,每一公里价格变为3元。
设计程序如下:
module CNT1(clK,rst,Mil,Q,A);
input [9:0]Mil;
input [5:0]Q;
input clK,rst;
output reg [9:0]A;//A表示价格
reg [2:0]X;//D1表示价格,X:等待时间超过3分钟的变量;Mil1表示价格刚超过50元时的行驶路程
always@ (posedge clK or negedge rst)
begin
if(rst==0)
begin
A<=0;
X<=0;
end
else
begin
if(Q<=3)
begin
if(Mil<=30)
begin
A<=7'd100;
end
else if(30<Mil&&Mil<=230)
begin
A<=10*4'd10+(Mil-30)*2'd2;
end
else
begin
A<=50*4'd10+(Mil-230)*2'd3;
end
end
else
begin
if(Mil<=30)
begin
A<=(10+Q-2'd3)*4'd10;
end
else if(30<Mil)
begin
X<=2;
A<=(7+Q)*4'd10+(Mil-30)*X;
if(A<=500)
begin
X<=2;
end
else
begin
X<=3;
//A<=(7+Q)*4'd10+(Mil-30)*X-(7'd245-5*Q);
A<=8'd382+(Mil-7'd245+5*Q)*3-(Q-3)*5;
end
end
end
end
end
endmodule
由程序分析可知:
当输入信号rst为1时,即为高电平,程序开始工作,当输入信号rst为1,即低电平,此时全部清零。
当输入信号Q小于等于3时,且路程小于等于3公里,输出价格为10元。
当输入信号Q小于等于3时,路程大于3公里小于23公里时,金额计算公式为起步价10元+(公里数-3)*2。
当输入信号Q大于3时,且路程小于3公里,金额为10元+(等待时间-3)*1。
当输入信号Q大于3时,且路程大于3公里但总金额不超过50元,
金额=10+(等待时间-3)*1+(路程-3)*2。
当输入信号Q大于3时,且总金额大于50时,金额计算公式如下:
金额=10+(等待时间-3)*1+(路程-3)*3-(50元所对应的路程)
3.4.2 仿真结果
根据上面的程序,利用EDA软件Quartus II进行仿真,计费模块的功能仿真如图4-4所示。
图4-4:计费模块仿真结果
由仿真图可知:
为方便显示模块显示,对输出的数字进行扩大10倍处理,即230表示23公里,100表示10元,3分钟依旧是3分钟。
由仿真结果图分析可知:
当输入信号rst高电平,计费器开始工作。
当输入信号Q小于等于3时,在里程为23公里时,金额刚好为50元,之后再多行驶1公里,金额变为53元。
当输入信号Q大于3公里时,以5分钟举例,当路程数为22时,刚好金额为50元,多行驶1公里后,金额变为 53元,此时等待时间又多等了一分钟,总金额变为54元。
3.5 寄存模块设计
3.5.1 寄存模块程序设计
寄存模块主要对应之前模块产生的数据进行一次处理,方便显示模块的显示,输入信号有内部时钟信号clk,计时信号TA,里程信号MA,金额信号DA,还有8个输出信号:
t0:表示等待时间的个位
t1:表示等待时间的十位
m0:表示行驶里程的十分位
m1:表示行驶里程的个位
m2:表示行驶里程的十位
d0:表示金额的十分位
d1:表示金额的个位
d2:表示金额的十位
设计程序如下:
module DF(clk,TA,MA,DA,t0,t1,m0,m1,m2,d0,d1,d2);
input clk;
input [5:0]TA;
input [9:0]MA,DA;
output reg[3:0]t0,t1,m0,m1,m2,d0,d1,d2;
always @(posedge clk)
begin
t0=TA%10;
t1=TA/10%10;
m0=MA%10;
m1=MA/10%10;
m2=MA/100%10;
d0=DA%10;
d1=DA/10%10;
d2=DA/100%10;
end
endmodule
由程序分析可知:
此程序只有简单的整除、取余算法,以此来得到对应位数的想要数字。
3.5.2 仿真结果
根据上面的程序,利用EDA软件Quartus II进行仿真,寄存器模块的功能仿真如图4-5所示。
图4-5:寄存器模块
由仿真图可知:
输入的金额和里程均为扩大了10倍.
当输入的金额是128时,由此模块输出得到十分位的8,个位的2,十位的1;
当输入的里程是41时,由此模块输出得到的十分位是1,个位是4,十位是0;
当输入的等待时间是4时,由此模块输出得到的个位是4,十位是0。
3.6 显示的分频器模块设计
3.6.1 显示分频器模块程序设计
此模块主要对系统内部时钟频率进行处理,以此得到数码管显示的频率信号。输入信号有clk内部时钟信号,输出信号Q1,f0。
设计程序如下:
module div2(clk,Q1,f0);
input clk;
output reg [2:0]Q1,f0;
reg [15:0]scan_cnt;
always @(posedge clk)
begin
if(scan_cnt<62499)
begin
scan_cnt=scan_cnt+1;
end
else
begin
scan_cnt=0;
if(f0==8)f0=0;
else f0=f0+1;
if(Q1==8)Q1=0;
else Q1=Q1+1;
end
end
endmodule
由程序分析可知:
对时钟信号的下降沿进行检测,存在一个中间变量scan_cnt,记录到一次下降沿,scan_cnt就+1,当其等于62499时,清零,并f0 Q1进行加一,最大值不超过8。
3.6.2 仿真结果
根据上面的原理图程序,利用EDA软件Quartus II进行综合和仿真,显示分频器模块的功能仿真如图所示。
图4-6:显示分频器模块仿真图1
由图分析可知:
系统检测时钟的上升沿,当scan_cnt累加到62499后,Q1和f0分别加1,其中f0和Q1均代表的是数码管位码。
3.7 显示模块设计
3.7.1 显示模块程序设计
此模块主要作用是对之前模块产生的各种数据进行处理,显示到数码管上,最终输出段码和位码。
程序设计代码如下:
//数码管及译码器
module DISP(f,q,T0,T1,M0,M1,M2,D0,D1,D2,duan,wei);
input [3:0]f,q;
input [3:0]T0,T1,M0,M1,M2,D0,D1,D2;
output reg [7:0]duan,wei;
reg [3:0]dout;
always @(f) //位选
begin
case(f)
0:begin wei=8'B0111_1111; dout=T1; end
1:begin wei=8'B1011_1111; dout=T0; end
2:begin wei=8'B1101_1111; dout=M2; end
3:begin wei=8'B1110_1111; dout=M1; end
4:begin wei=8'B1111_0111; dout=M0; end
5:begin wei=8'B1111_1011; dout=D2; end
6:begin wei=8'B1111_1101; dout=D1; end
7:begin wei=8'B1111_1110; dout=D0; end
default begin wei=8'B1111_1111; dout=0;end
endcase
end
always @(q)
begin
if(q!=3&&q!=6)
begin //段选
case(dout)
00: duan=8'B11000000;
01: duan=8'B11111001;
02: duan=8'B10100100;
03: duan=8'B10110000;
04: duan=8'B10011001;
05: duan=8'B10010010;
06: duan=8'B10000010;
07: duan=8'B11111000;
08: duan=8'B10000000;
09: duan=8'B10010000;
default duan=8'B11111111;
endcase
end
else
begin //段选
case(dout)
00: duan=8'B01000000;
01: duan=8'B01111001;
02: duan=8'B00100100;
03: duan=8'B00110000;
04: duan=8'B00011001;
05: duan=8'B00010010;
06: duan=8'B00000010;
07: duan=8'B01111000;
08: duan=8'B00000000;
09: duan=8'B00010000;
default duan=8'B01111111;
endcase
end
end
endmodule
由程序分析可知:
通过输入的f和q来进行选择位码,同时,由于小数点的存在,将小数点设置在特定的位置所以,在q等于3或者等于6时,将对应的段码进行首个数字进行置0。
数码管布局如下
[ 时间 ] [ 时间 ] [ 里程 ] [ 里程 ] [ 里程 ] [ 金额 ] [ 金额 ] [ 金额 ]
3.7.2 仿真结果
根据上面的原理图程序,利用EDA软件Quartus II进行综合和仿真,显示模块的功能仿真如图所示。
图3-7:显示模块仿真图
由图可知:
输入金额为15.6元,行驶路程为3.3公里,等待时间为5分钟。
对应仿真显示:
0 5 0 3. 3 1 5. 6
分别在第二位和第五位固定显示小数点。
3.8 顶层模块设计
3.8.1 顶层模块程序设计
设计程序如下:
module TAXI2(Clk,Rst,Key1,Key2,DUAN,WEI);
input Clk,Rst,Key1,Key2;
output [7:0]WEI,DUAN;
wire F0,F1;
wire [5:0]t;
wire [3:0]ta,tb,ma,mb,mc,da,db,dc;
wire [3:0]A,B;
wire [9:0]LU,money;
div u1(.clk(Clk),.f1(F1),.f0(F0),.rst(Rst));
control u2(.key1(Key1),.key2(Key2),.rst(Rst),.clk_1(F0),.mil(LU));
clock u3(.clk_2(F1),.key2(Key2),.rst(Rst),.Q(t));
CNT1 u4(.clK(Clk),.rst(Rst),.Mil(LU),.Q(t),.A(money));
div2 u5(.clk(Clk),.Q1(A),.f0(B));
DFu6(.clk(Clk),.TA(t),.MA(LU),.DA(money),.t0(ta),.t1(tb),.m0(ma),.m1(mb),.m2(mc),.d0(da),.d1(db),.d2(dc));
DISPu7(.q(A),.f(B),.T0(ta),.T1(tb),.M0(ma),.M1(mb),.M2(mc),.D0(da),.D1(db),.D2(dc),.duan(DUAN),.wei(WEI));
endmodule
图3-8-1顶层流程图
由程序分析可知:
有四个输入信号,两个输出信号,Clk时钟信号,Rst清零信号,Key1控制汽车行驶,Key2控制汽车暂停,等待时间开始计算,DUAN , WEI为输出信号。控制逻辑如下:
Key1为0,Key2为0,此时由于汽车没有行驶,自动计算等待时间;
Key1为1,Key2为0,此时汽车开始行驶,计算行驶路程;
Key1为0,Key2为1,此时行驶路程暂停,等待时间开始计算;
Key1为1,Key2为1,此时所有计算暂停,金额停止计算;
Key1,Key2为0,Rst按下,全部清零。
硬件测试结果
硬件下载的结果如下图所示。
图4-2:等待时间3分钟,未进行行驶,金额为10元
图4-3:等待时间3分钟,行驶3公里,金额10元
由上两组图可与看出,等待时间在3分钟内,行驶路程在3公里内,均为10元。
图4-4:等待时间3分钟,行驶路程4公里,金额12元
由上图可以得知:当行驶路程超过3公里后,每行驶一公里2元。
图4-5:等待时间5分钟,行驶路程22公里,金额为50元。
刚好金额为50元的情况。
图4-6:金额超过50元的情况
由上图可知:当金额超过50元后,每公里3元。