出租车计费器课程设计报告VHDL语言.docx
《出租车计费器课程设计报告VHDL语言.docx》由会员分享,可在线阅读,更多相关《出租车计费器课程设计报告VHDL语言.docx(22页珍藏版)》请在冰豆网上搜索。
出租车计费器课程设计报告VHDL语言
电子技术课程设计
—出租车计费器的设计
学院:
电子信息工程学院
班级:
姓名:
学号:
指导教师:
日期:
年月日
出租车计费器设计
一、设计任务与要求
设计并制作一台出租车计费系统,要求如下:
﹙1﹚实现计费功能,计费标准为:
按行程里程收费,起步价为7.00元,在车行3公里后再按2.2元/公里计费,当计费器达到或超过20元时,每公里加收50﹪的车费。
﹙2﹚实现模拟功能:
能模拟汽车启动、停止、暂停、加速的状态
﹙3﹚设计动态扫描电路,将车费和里程显示出来,各有两位小数。
二、总体框图
(1)系统总体结构
出租车计费器的组成如上图所示,各部分主要功能包括输入信号模块对车轮传感器传送的脉冲信号进行计数,并以高低脉冲模拟出租汽车启动,停止,暂停,加速按钮,具有输入信号作用;数据转换器模块将计费模块输出的车费和路程转换成4位的十进制数据;译码/动态扫描模块将路程与费用的数值译码后用动态扫描的方式驱动数码管;数码管显示模块将公里数和计费金额均用4位LED数码管显示。
(2)其流程图如下图所示:
(3)各模块设计功能及设计思路
★信号输入模块
该模块主要实现计费功能和现场模拟功能。
计费标准为:
按行驶里程计费,起步价为7.00元,并在车行3km后按2.20元/km计费,当计费器达到或超过20元时,每公里加收50%的车费,车停止不计费。
并以高低脉冲模拟出租汽车启动、停止、暂停、加速按钮,具有输入信号的作用。
★数据转换模块
数据转换模块是一个模为10的加法计数器,可将计费模块输出的车费和路程转换成4位的十进制数。
★显示模块
显示模块是由七段LED数码管译码和动态扫描显示两部分组成。
采用的是共阴极七段数码管,根据十六进制数和七段显示段码表的对应关系,其中要求路程和车费都要用2位小数点来表示,所以须设置一个控制小数点的变量,即程序中的dp。
这段程序所示的是在数码管的第二、第六个后面显示小数点,实现了路程和车费都用2位小数点表示的功能。
数码管控制及译码显示模块将十进制的输入信号用七段数码管显示,由七段发光二极管组成数码显示器,利用字段的不同组合。
可分别显示0~9十个数字。
★片选信号产生模块
片选信号产生模块是对数码管进行片选并让其能够按照要求显示数据的模块
三、选择器件
设计开发软件:
QuartusII6.0
EDA实验箱:
EL教学实验箱
四、功能模块
(1)jifei模块
此模块为计费模块(即总体结构中的信号输入模块),实现计费功能,计费标准为:
按行驶里程计费,起步价为7.00元,并在车行3公里后按2.20元/km计费,当计数器达到或超过20元时,每公里加收50%的车费,即按3.30元/km计费。
CLK、START、STOP、PAUSE、JS为输入信号,分别代表汽车的起动、停止、暂停和加速,CLK为扫描时钟,硬件实现时加入时钟信号,另有两个输出,即CHEFEI和LUC,分别代表车费和路程,当车处于行驶状态时,此模块会自动记录下路程与车费状况并作为转换模块的输入。
jifei模块源程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityjfmkis
port(clk,start,stop,pause,js:
instd_logic;
chefei,luc:
outintegerrange0to8000);
endjfmk;
architectureoneofjfmkis
begin
process(clk,start,stop,pause,js)
variablea,b:
std_logic;
variableaa:
integerrange0to100;
variablechf,lc:
integerrange0to8000;
variablenum:
integerrange0to9;
begin
if(clk'eventandclk='1')then
if(stop='0')then
chf:
=0;
num:
=0;
b:
='1';
aa:
=0;
lc:
=0;
elsif(start='0')then
b:
='0';
chf:
=700;
lc:
=0;
elsif(start='1'andjs='1'andpause='1')then
if(b='0')then
num:
=num+1;
endif;
if(num=9)then
lc:
=lc+5;
num:
=0;
aa:
=aa+5;
endif;
elsif(start='1'andjs='0'andpause='1')then
lc:
=lc+1;
aa:
=aa+1;
endif;
if(aa>=100)then
a:
='1';
aa:
=0;
else
a:
='0';
endif;
if(lc<300)then
null;
elsif(chf<2000anda='1')then
chf:
=chf+220;
elsif(chf>=2000anda='1')then
chf:
=chf+330;
endif;
endif;
chefei<=chf;
luc<=lc;
endprocess;
endone;
模块分析:
首先打开ieee库,用use语句声明使用std_logic_1164和std_logic_unsigned程序包。
clk、start、stop、pause、js为敏感信号,定义a,b为中间变量,变量aa、num、chf为位矢量。
当时钟上升沿到来时,如果STOP='0'则chf:
=0,num:
=0,b:
=1,aa:
=0,lc:
=0,如果stop='1'且start='0'则chf:
=700,lc:
=0,stop='1’;如果stop='1'andstart='1'andjs='1'andpause='1'且b='0'则num:
=num+1;如果stop='1'andstart='1'andjs='1'andpause='1'且num=9则lc:
=lc+1;num:
=0,aa:
=aa+1。
如果stop='1'andstart='1'andjs='0'andpause='1'则lc:
=lc+1;aa:
=aa+1;以上各状态分别代表汽车的停止、启动、加速、暂停。
如果aa>=100则a:
='1',aa:
=0,否则a:
='0',如果chf<2000且a='1'则chf:
=chf+220;如果chf>2000anda='1'则chf:
=chf+330;以上各状态表示汽车在三公里以外车费在二十元以内的状态、车费在二十元以外的状态。
结束进程,结束结构体。
jifei模块的时序仿真图:
时序仿真图分析:
图中的stop为汽车停止输入端,上升沿有效;start为汽车启动输入端,上升沿有效;pause为汽车暂停输入端,上升沿有效;js为汽车加速输入端,上升沿有效。
CLK为时钟源信号;chefei为汽车车费输出端,luc为汽车路程输出端。
由图可知:
当stop,Start,pause,js全为高电平时路程按5的速度增加,车费为700.当路程增加到300时,车费变为920,以后路程每增加100,车费增加220。
模块生成图:
(2)x模块
此模块为数据转换模块,功能是将计费模块产生的车费与路程的模拟量转换成数字量并输出,它是一个模为10的加法计数器,可将计费模块输出的车费和路程转换成4位的十进制数。
其中DACLK为时钟信号,ASCORE、BSCORE连接计费模块的CHEFEI和LUC,输出为2个4位的十进制数,可以分别表示路程和车费情况。
当车运行于不同状况时,此模块会将不同的车费与路程状况转换为数字量并输出。
x模块的源程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityxis
port(daclk:
instd_logic;
ascore,bscore:
inintegerrange0to8000;
age,ashi,abai,aqian,bge,bshi,bbai,bqian:
outstd_logic_vector(3downto0));
endx;
architecturert1ofxis
begin
process(daclk,ascore)
variablecomb1:
integerrange0to8000;
variablecomb1a,comb1b,comb1c,comb1d:
std_logic_vector(3downto0);
begin
if(daclk'eventanddaclk='1')then
if(comb1if(comb1a=9andcomb1b=9andcomb1c=9)then
comb1a:
="0000";
comb1b:
="0000";
comb1c:
="0000";
comb1d:
=comb1d+1;
comb1:
=comb1+1;
elsif(comb1a=9andcomb1b=9)then
comb1a:
="0000";
comb1b:
="0000";
comb1:
=comb1+1;
comb1c:
=comb1c+1;
elsif(comb1a=9)then
comb1a:
="0000";
comb1b:
=comb1b+1;
comb1:
=comb1+1;
else
comb1a:
=comb1a+1;
comb1:
=comb1+1;
endif;
else
ashi<=comb1b;
age<=comb1a;
abai<=comb1c;
aqian<=comb1d;
comb1:
=0;
comb1a:
="0000";
comb1b:
="0000";
comb1c:
="0000";
comb1d:
="0000";
endif;
endif;
endprocess;
process(daclk,bscore)
variablecomb2:
integerrange0to8000;
variablecomb2a,comb2b,comb2c,comb2d:
std_logic_vector(3downto0);
begin
if(daclk'eventanddaclk='1')then
if(comb2if(comb2a=9andcomb2b=9andcomb2c=9)then
comb2a:
="0000";
comb2b:
="0000";
comb2c:
="0000";
comb2d:
=comb2d+1;
comb2:
=comb2+1;
elsif(comb2a=9andcomb2b=9)then
comb2a:
="0000";
comb2b:
="0000";
comb2:
=comb2+1;
comb2c:
=comb2c+1;
elsif(comb2a=9)then
comb2a:
="0000";
comb2b:
=comb2b+1;
comb2:
=comb2+1;
else
comb2a:
=comb2a+1;
comb2:
=comb2+1;
endif;
else
bshi<=comb2b;
bge<=comb2a;
bbai<=comb2c;
bqian<=comb2d;
comb2:
=0;
comb2a:
="0000";
comb2b:
="0000";
comb2c:
="0000";
comb2d:
="0000";
endif;
endif;
endprocess;
endrt1;
程序分析:
首先打开ieee库,用use语句声明使用std_logic_1164和std_logic_unsigned程序包。
定义实体,daclk、ascore、bscore为输入,age、ashi、abai、aqian、bge、bshi、bbai、bqian为输出位矢量。
然后定义结构体,daclk、ascore、bscore为敏感信号,定义变量comb1a,comb1b,comb1c,comb1d为位矢量,变量comb1为0到7000范围。
当时钟上升沿到来时,各个变量分别实现个、十、百、千的进位。
然后实现一个循环。
然后再将各个变量付给各个位矢量。
模块生成图:
X模块的时序仿真图
时序仿真图的分析转换模块的时序仿真图如下图所示:
可见能将路程和车费转换为4位的十进制数,便于8位数码管显示。
由图可知:
当ascore,bscore为13位二进制数,当ascore为0-9时age从0到9变化,当ascore为10时age等于0,ashi等于1。
当bscore为0-9时bge从0到9变化,当bscore为10时bge等于0,bshi等于1。
(3)sel模块
此模块为片选信号产生模块,功能是选择八段数码管按照设计要求进行正确的显示。
其具体的对应关系如下表所示:
接口序号
数码管
SEL2
SEL1
SEL0
状态
1
1
1
第1位亮
1
1
0
第2位亮
1
0
1
第3位亮
1
0
0
第4位亮
0
1
1
第5位亮
0
1
0
第6位亮
0
0
1
第7位亮
0
X
X
第8位亮
在该模块中CLK为时钟信号,A[2..0]为片选输出,用于选择数码管,连接译码显示模块的片选端C[2..0]。
se模块的源程序如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityselis
port(clk:
instd_logic;
a:
outstd_logic_vector(2downto0));
endsel;
architecturert1ofselis
begin
process(clk)
variableb:
std_logic_vector(2downto0);
begin
if(clk'eventandclk='1')then
if(b="111")then
b:
="000";
else
b:
=b+1;
endif;
endif;
a<=b;
endprocess;
endrt1;
生成se模块:
sel模块的波形图:
由图可以看出,当CLK加入时钟信号时,a从000到111逐个变化,该模块可将模拟信号进行片选并有对应的数码管进行显示。
(4)xxx1模块
此模块为显示模块中的动态扫描/译码/数码管显示模块,功能是将已转换好的数字量加载到两个4位七段数码管上并加以显示。
C[2..0]为片选端,用来连接片选模块的片选输出端A[2..0],A1、A2、A3、A4、B1、B2、B3、B4分别连接数据转换模块的八个转换输出端,因为设计要求路程和车费都要用2位小数点来表示,所以须设置一个控制小数点的变量,即程序中的DP端,D[3..0]连接数码管控制模块的输入端。
xxx1模块的源程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityxxxlis
port(c:
instd_logic_vector(2downto0);
dp:
outstd_logic;
a1,a2,a3,a4,b1,b2,b3,b4:
instd_logic_vector(3downto0);
d:
outstd_logic_vector(3downto0));
endxxxl;
architecturertlofxxxlis
begin
process(c,a1,a2,a3,a4,b1,b2,b3,b4)
variablecomb:
std_logic_vector(2downto0);
begin
comb:
=c;
casecombis
when"000"=>d<=a1;
dp<='0';
when"001"=>d<=a2;
dp<='0';
when"010"=>d<=a3;
dp<='1';
when"011"=>d<=a4;
dp<='0';
when"100"=>d<=b1;
dp<='0';
when"101"=>d<=b2;
dp<='0';
when"110"=>d<=b3;
dp<='1';
when"111"=>d<=b4;
dp<='0';
whenothers=>null;
endcase;
endprocess;
endrtl;
生成模块:
xxx1模块的时序仿真图:
由上图可知,输入信号C为3位片选信号其变化范围为0到7,输入信号c从0到7逐个变化时,输出d逐个输a1,a2,a3,a4,b1,b2,b3,b4的输入信号。
(5)di模块
此模块为数码管控制模块,功能是控制七段数码管对转换后的数字量进行显示,使其完成路程和车费的显示。
其中D[3..0]连接动态扫描/译码/数码管显示模块的D[3..0]端,Q[6..0]连接七段数码管,利用其控制特性在数码管上显示出车费和路程。
di模块的源程序:
libraryieee;
useieee.std_logic_1164.all;
entitydiis
port(d:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(6downto0));
enddi;
architecturertlofdiis
begin
process(d)
begin
casedis
when"0000"=>q<="0111111";
when"0001"=>q<="0000110";
when"0010"=>q<="1011011";
when"0011"=>q<="1001111";
when"0100"=>q<="1100110";
when"0101"=>q<="1101101";
when"0110"=>q<="1111101";
when"0111"=>q<="0100111";
when"1000"=>q<="1111111";
whenothers=>q<="1101111";
endcase;
endprocess;
endrtl;
生成模块:
di模块的时序仿真图:
从波形图中可看出,此模块可控制数码管完成对数字量的显示。
当输入为0000-1000时数码管分别显示0,1,2,3,4,5,6,7,8。
当输入为其他时数码管显示9。
(6)div模块
div模块将实验箱上50Mhz脉冲信号分频为500hz。
div模块源程序:
LIBRARYieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
ENTITYdivIS
port(clk:
INstd_logic;
clkout:
OUTstd_logic
);
enddiv;
ARCHITECTUREoneOFdivIS
BEGIN
process(clk)
variablecnt:
integerrange0to100000;
variabletmp:
std_logic;
begin
ifclk'eventandclk='1'then
ifcnt>=99999then
cnt:
=0;
tmp:
=nottmp;
else
cnt:
=cnt+1;
endif;
endif;
clkout<=tmp;
endprocess;
endone;
div生成模块图:
div模块时序仿真波形:
div将时钟信号分频,使频率减小。
(7)decode3_8模块
sel通过decode3_8模块选择数码管
decode3_8模块源程序:
LIBRARYieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
ENTITYdecode3_8IS
PORT(SEL:
INstd_logic_vector(2downto0);
Q:
OUTstd_logic_vector(7downto0));
ENDdecode3_8;
ARCHITECTUREaOFdecode3_8IS
BEGIN
Q<="11111110"whensel=0else
"11111101"whensel=1else
"11111011"whensel=2else
"11110111"whensel=3else
"11101111"whensel=4else
"11011111"whensel=5else
"10111111"whensel=6else
"01111111"whensel=7else
"11111111";
ENDa;
decode3_8生成模块图:
decode3_8模块时序仿真波形图:
decode3_8模块选择数码管,当sel信号从0-7变化时,依次选择1-8八个数码管。
五、总体设计电路图
整体工作情况:
(1)模块连接:
计费模块的clk、start、stop、pause和js端连接输入,chefei[12..0]和luc[12..0]连接转换模块的ascore[12..0]与bscore[12..0];
转换模块的daclk端连接输入,age[3..0]至bqian[3..0]连接动态扫描/译码/数码管显示模块的a1[3..0]至b4[3..0];
动态扫描/译码/数码管显示模块的C[2..0]连接片选输出SEL[2..0],DP端连接输出DP,D[3..0]连接数码管控制模块的D[3..0];
片选信号产生模块的CLK端与输入信号相连,并连接转换模块的DACLK端,A[2..0]连接片选输出SEL[2..0],并与动态扫描/译码/数码管显示模块的C[2..0]相连;
数码管控制模块的D[3..0]端与动