📄 taxi_fee_counter.txt
字号:
在日常生活中,总费用包括起步费用和每公里行驶费用两部分,中途停车时不进行计费。同时还应考虑到下面几种特殊情况:起步里程结束后才开始每公里计费统计,在汽车加速时行驶路程较远,所以应该在汽车加速时适当调整路程计数;行驶较远的路程,应该考虑每公里的单价提升。上述要求都应该通过可控制的开关实现。
按照上面的要求,对计费模块作出如下设定:按行驶里程计费,起步价格为7.00元,起步里程为3公里,行驶超出3公里后每公里费用为2.20元,当计费器达到20元后,每公里加收50%的车费(3.30元)。
port(clk,start,stop,pause,js:in std_logic;
chefei,luc:out integer range 0 to 8000);
以上为jifei模块的端口设定,clk为时钟频率输入,start,stop,pause,js分别为汽车起动、停止、暂停、加速开关。由这些开关可以控制
计费器按照车辆的行驶状态正确计费。路程和费用上限为80公里/元。
if(clk'event and clk='1')then
if(stop='0')then
chf:=0;
num:=0;
b:='1';
aa:=0;
lc:=0;
时钟上升沿启动下列程序(包括后续程序),当stop='0'(未停止时),中间寄存器chf(费用)lc(路程)清零。
elsif(start='0')then
b:='0';
chf:=700;
lc:=0;
当stop<>'0'时(停止) 当start='0'(汽车未起动) 中间寄存器chf记录起步价格7.00元,其他清零。
elsif(start='1'and js='1'and pause='1')then
if(b='0')then
num:=num+1;
end if;
if(num=9)then
lc:=lc+5;
num:=0;
aa:=aa+5;
end if;
当stop<>'0'时(停止)当汽车起动且加速且暂停时 如果是汽车刚刚起动,开始加速(b=0)num开始累加 如果加速到累加到num=9,进行加速路程统计,按匀速行驶的5倍路程计数。
elsif(start='1'and js='0' and pause='1')then
lc:=lc+1;
aa:=aa+1;
end if;
if(aa>=100)then
a:='1';
aa:=00;
else
a:='0';
end if;
当stop<>'0'时(停止) 当汽车起动且不加速且暂停时 路程累加1,如果路程到1公里,路程标志a记为'1' 路程中间寄存器aa清零
否则路程标志不计。
if(lc<300)then
null;
当行驶里程小于3公里,不进行计费。
elsif(chf<2000 and a='1')then
chf:=chf+220;
elsif(chf>=2000 and a='1')then
chf:=chf+330;
end if;
大于3公里,如果车费小于20元,车费每公里2.20元计算,大于20元,车费每公里3.30元计算。
end if;
chefei<=chf;
luc<=lc;
结束各个判断条件,把中间寄存器的值付给输出端口输出。
2.2转换模块(x)
该模块用做把车费和路程转换为4位十进制数,为用LED显示器显示数字做准备。从daclk这一时钟信号的上升沿开始,daclk的频率要远高于clk的频率。
port(daclk:in std_logic;
ascore,bscore:in integer range 0 to 8000;
age,ashi,abai,aqian,bge,bshi,bbai,bqian:out std_logic_vector(3 downto 0));
ascore作为车费的输入,bscore作为路程的输入。age....aqian作为费用数据转换后的4位十进制的个、十、百、千位输出
bge...作为路程数据转换后输出。
architecture rt1 of x is
begin
process(daclk,ascore)
variable comb1:integer range 0 to 8000;
variable comb1a,comb1b,comb1c,comb1d:std_logic_vector(3 downto 0);
comb*作为中间寄存器,数据类型和范围同前面的端口相同。
begin
if(daclk'event and daclk='1')then
if(comb1<ascore)then
if(comb1a=9 and comb1b=9 and comb1c=9)then
comb1a:="0000";
comb1b:="0000";
comb1c:="0000";
comb1d:=comb1d+1;
comb1:=comb1+1;
在daclk时钟上升沿,当寄存器中数据小于输入数据时,如果个,十,百位为9,那么将这些位清零,同时将千位加1,comb1也加1, 做千位的10进位。
elsif(comb1a=9 and comb1b=9)then
comb1a:="0000";
comb1b:="0000";
comb1:=comb1+1;
comb1c:=comb1c+1;
做百位的10进位
elsif(comb1a=9)then
comb1a:="0000";
comb1b:=comb1b+1;
comb1:=comb1+1;
做十位的10进位
else
comb1a:=comb1a+1;
comb1:=comb1+1;
end if;
在个位时,个位和整个费用输入寄存器都加1即可
else
ashi<=comb1b;
age<=comb1a;
abai<=comb1c;
aqian<=comb1d;
comb1:=0;
comb1a:="0000";
comb1b:="0000";
comb1c:="0000";
comb1d:="0000";
end if;
end if;
end process;
当寄存器中数据不小于输入数据时,也就是jifei模块停止向x模块输出车费数据时,将各寄存器中数据输入到输出端口,寄存器清零
路程转换器与费用转换器设计方法相同,只是寄存器名称改为b*。
2.3 显示模块
显示模块由下列两个部分组成:扫描选择部分(se和xxx1),译码部分(di)
2.3.1 扫描选择部分(se和xxx1)
if(clk'event and clk='1')then
if(b="111")then
b:="000";
else
b:=b+1;
end if;
end if;
a<=b;
此处clk频率即上面提及的daclk频率,程序在时钟上升沿启动,b寄存器到达最大值时清零,否则进行累加,结果输出。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -