出租车计费器的FPGA实现含VHDL代码.docx
《出租车计费器的FPGA实现含VHDL代码.docx》由会员分享,可在线阅读,更多相关《出租车计费器的FPGA实现含VHDL代码.docx(19页珍藏版)》请在冰豆网上搜索。
出租车计费器的FPGA实现含VHDL代码
可编程逻辑器件电路设计
课程设计报告
出租车计费器的FPGA实现
华南农业大学工程学院
摘要
出租车计费系统利用VHDL语言,以MAX+PLUSⅡ软件作为开发平台而设计。
系统包括五大模块——主控模块、分频模块、里程模块、计费模块和显示模块;预置和模拟汽车启动、停止、计费、暂停等功能,并动态扫描显示车费与里程。
关键词:
出租车计费系统VHDL语言MAX+PLUSⅡFPGA数字系统
1.方案比较与选择
1.1方案一
图1图2出租车计费器方案一原理框图
1.1.1出租车计费器方案一原理
基于CPLD/FPGA的出租车的组成如图1所示。
各部分主要的功能如下:
(1)A计数器对车轮的传感器送来的脉冲信号进行计数(每转一圈送一个脉冲)。
不同车型的车轮可能不一样,通过“设置1”对车型做出选择,以实现对不同车型直径的车进行调整。
(2)B计数器对百米脉冲进行累加,并输出实际的公里数的BCD码给出译码动态扫描模块。
每计,满500送出一个脉冲给出C计数器。
“设置2”实现起步公里数预制。
(3)C计数器实现步长可变(即单价可调)的累加计数,每500米计费一次。
“设置3”用来完成超价加费,起步价预制等。
(4)译码/动态扫描见路程与费用的数字译码后动态扫描的方式驱动数码管。
(5)数码管显示将公里数和计费金额平均用四位数码管显示(三位整数,1为小数)
1.1.2出租车计费器方案一优点
根据车型的车轮直径来进行脉冲调整,因为实际车轮大小并非完全一致,需要根据实际大小而重新设置;起步价调整。
起步价调整解决了由于地域的同步而导致起步价的不同,从而是出租车计费系统有更广和广阔的市场,同时也解决了由于起步价调整而更换计费系统的问题。
1.1.2出租车计费器方案一缺点
计费系统的精度不高,里程计费精度太低,在设计过程中设置车轮的直径过于复杂,不利于系统的完成。
1.2方案二
图2出租车计费器方案二原理框图
1.2.1出租车计费器方案二原理
基于FPGA设计的出租车计费器系统如图2所示,各模块功能如下:
(1)分频模块:
分频模块主要采用的是加法分频电路,该分频器为十分频电路,并且分频器带有“开始“/”“清零”端(ENABLE3为高电平是开始),将分频得CLK2用于里程计费模块的脉冲。
(2)车态模块:
车态模块主要利用状态机原理。
将出租车计费系统设置成四个状态,STATE=“00”实现的是清零操作;STATE=“01”是显示在行驶3km以内,只收起步价7.00元状态;STATE=“10”是车行驶超过3km后,按每公里2.2元计费;STATE=“11”行驶路程达到或超过9km后(车费达到20元),每公里加收50%的车费,车费变成按每公里3.3元开始计费。
并把每一状态传输给计费模块。
(3)控制模块:
控制模块属于整个出租车系统的顶层文件,负责这个系统,T_CLR是清零键,即归零显示;T_STO是暂停信号;T_ENABLE是使能信号,是启动键,T_ENABLE=’0’时启动计费器。
(4)里程模块:
里程模块的一个基准时钟,实现加0.1公里,并将十进制数转化成四位BCD码,传输给显示电路显示。
(5)计费模块:
计费模块接收来自车态模块的状态信号和分频电路的十分频脉冲作基准时钟。
计费模块设置了四个状态,第一个状态保持属于清零状态,第二状态保持显示“007.0”,第三个状态实现一个脉冲加2.2,第四个状态是一个脉冲加3.3。
将十进制的计费转化成BCD传输给显示模块。
(6)显示模块:
显示模块是由七段LED数码译码和动态扫描两部分组成。
采用的是共阴极数码管,根据十六进制数和七段显示段码表的对应关系,其中要求路程和车费毒药用一位小数点来表示,所以须要设置一个控制小数点的变量,即程序中的DP。
这段程序所示的是在数码管的第二、六个数码管后面的显示小数点,实现了路程和车费都用1位小数点表示的功能,要主要的是选择的扫描频率不合适,可能会出现小数点闪动的情况。
但只要扫描频率不少于24HZ,人眼就感觉不到数码管的闪烁。
数码管控制及译码显示模块将BCD信号的输入用七段数码管显示,由七段发光二极管组成数码显示,利用字段的不同组合,可表示0-9十个数字。
1.2.2出租车计费器方案二优点
方案二继承了方案一优点,并有效的解决了方案一的精度低的缺点,并且在原件设计上容易实现。
1.2.2出租车计费器方案二缺点
系统的模块过多,不利于顶层文件的实现。
1.2.2出租车计费器方案二可行性
系统各个模块的设计相对于方案一容易,特别是分频模块和车态模块。
2.底层文件仿真与分析
2.1出租车计费器系统电路
图3出租车计费器系统电路
2.1.1分频模块分析及仿真图
分频电路实现的功能是:
将里程模块的基准时钟进行十分频,即CLK0每来四个脉冲,该模块即将一个脉冲发出,作为计费模块的基准时钟,如图4所示。
图4分频模块仿真图
2.1.2车态模块分析及仿真
当车处于暂停时,车费保持值不变,定义此时ST的状态值为00;当车程小于3公里时,定义此时ST的状态值为01;车程大于3公里小于9公里时,定义此时ST的状态值为10;车程大于9公里时,定义此时ST的状态值为11,如图5所示。
图5车态模块仿真图
2.1.3计费模块仿真
当车程在3公里内时车费保持7元不变;当车程大于3公里小于9公里时,每来一个驱动脉冲相当于车前进了1公里,即车费要加2.2元;当车程大于9公里每来一个脉冲车费要加3.3元,如图6所示。
图6计费模块仿真图
2.1.4里程模块分析及仿真
里程模块是每一个脉冲到来,相当于车向前走了0.1公里,所以车程自加一公里,如图7所示。
图7里程模块仿真图
2.1.5显示模块仿真
采用8位动态扫描显示车费和车程,其中DI1-DI4是计费输入,DI5—DI6是里程输入,WEI是接入74LS138译码器,SG是数码管的七段显示接口。
当DI1-DI8输入“41753452”,WEI=‘0’时,第一个数码管应该显示4,对应数码管译码为“1100110”;当WEI=‘1’时,第二个数码管应该显示1,对应数码管译码“0000110”,转为十进制是‘6’,如图8所示。
图8显示模块仿真图
2.1.6顶层文件仿真与分析
顶层文件为出租车计费器控制模块,有五个输入端口,分别是T_CLR清零信号,低电平清零;T_ENABLE为使能信号,当使能信号为高电平时,开始计费,里程;T_STO为暂停信号,高电平有效;T_WEI是控制74LS138译码器的控制端,进行数码管的位选择,T_SG是控制数码管的段,实现数码管显示内容;T_DOT是第二位与第六位的小数点段,如图9、图10所示。
图9顶层文件仿真图
图10顶层文件仿真图局部放大图
4.硬件验证分析
程序代码在MAXPLUSII成功编写和仿真完毕,然后拷入FPGA。
硬件验证步骤及遇到的问题:
(1)装FPGA实验箱驱动。
由于实验前没有装驱动,结果当configure时,电脑显programinghardwareisbusy。
(2)在配置的时候,应该注意3.sof文件用于利用编程电缆ByteBlaster进行配置.而3.pof用于配置EPROM.(EPROM只能写入一次),所以在设计的时候,线可用编程电缆调试无误后,在写入EPROM中.
(3)代码下载成功后,发现数码管不能显示。
原因是:
把数码管的引脚在显示模块设置,而真正下载到实验箱的代码是顶层模块,导致数码管毫无显示。
正确是将端口设置全部设置在顶层模块中。
(4)在动态扫描中,小数点设置成了动态扫描的障碍。
解决方法是,将DP独立设置一位,不需要动态扫描。
因为小数点是不变的。
计费与里程的时钟不同步,导致计费和里程显示不同步。
出现,里程显示不变化,而计费开始。
(5)当使能信号开始时,并非显示000.0007.0,有乱码出现的情况,解决方法是设置初始化代码。
总体看来,这次硬件调试是很成功的,虽然中间遇到困难,都被一一解决,收获很大。
5.课程设计心得
这次课程设计中,我们主要是运用VHDL语言设计了一个出租车计费器,并且用层次化的设计方法来实现这个电路。
在程序编写结束后,我们还对该程序进行了调试,能按预期的效果进行模拟汽车启动、停止、暂停等功能,基本完成课程设计的要求。
通过此次课程设计,我们更进一步的深入了解了VHDL设计语言,并通过使用对它有了更深的体会。
对于编程过程中可能遇到的问题有了一定的了解,也明白了其中的一些注意事项,对于下次进行编程设计有很大的帮助和提高。
这次课程设计的最大收获在于我们学会了如何在软件仿真成功的基础上在实验箱上调试出我们所要的结果。
总之,这次实验不仅仅加强了我的动手编程能力,也大大加强了团队合作以及设计能力,使我在理论学习和编程练习方面都获得了较大的收获
Abstract
TaxibillingsystemusingVHDLlanguage,inordertoMAX+PLUSⅡsoftwareisdesignedasadevelopmentplatform.Systemconsistsoffivemodules-maincontrolmodule,sub-frequencymodule,mileagemodule,billingmoduleanddisplaymodule;presetsandanalogautostart,stop,billing,andpausefunctions,anddynamicallyscanshowsfareandmileage.
Keywords:
TaxibillingsystemVHDLlanguageMAXPLUSⅡFPGAdigitalsystem
参考文献
[1].潘松,黄继业.EDA技术实用教程.科学出版社.2005.2:
145~156.
[2].候伯亨,顾新.VHDL硬件描述语言与数字逻辑电路设计.西安电子科技大学.2004.11:
45~48.
附录(源代码)
一、10分频模块源代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYfenpinIS--10分频模块
PORT(CLK0:
INSTD_LOGIC;
FOUT:
OUTSTD_LOGIC;
ENABLE3:
INSTD_LOGIC);
ENDfenpin;
ARCHITECTUREONEOFfenpinIS
BEGIN
PROCESS(CLK0,ENABLE3)
VARIABLECNT:
STD_LOGIC_VECTOR(3DOWNTO0);--变量cnt
VARIABLEFULL:
STD_LOGIC;
BEGIN
IFENABLE3='0'THEN
CNT:
="1001";
ELSIFCLK0'EVENTANDCLK0='1'THEN--一个基准时钟为0.1公里
IFCNT="1001"THEN
CNT:
="0000";
FULL:
='1';
ELSE
CNT:
=CNT+1;
FULL:
='0';
ENDIF;
ENDIF;
FOUT<=FULL;--10分频后一个时钟为1公里,作为计费模块的驱动时钟
ENDPROCESS;
ENDONE;
二、车的计费模式控制模块源代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYchetaiIS
PORT(CLK:
INSTD_LOGIC;--车的计费模式控制模块
ENABLE:
INSTD_LOGIC;
STO:
INSTD_LOGIC;
CLR:
INSTD_LOGIC;
ST:
OUTSTD_LOGIC_VECTOR(1DOWNTO0));
ENDchetai;
ARCHITECTUREONEOFchetaiIS
BEGIN
PROCESS(CLK,ENABLE,STO,CLR)
VARIABLECQI:
STD_LOGIC_VECTOR(7DOWNTO0);
VARIABLESTATE:
STD_LOGIC_VECTOR(1DOWNTO0);
BEGIN
IFCLR='0'THENCQI:
=(OTHERS=>'0');
ELSIFCLK'EVENTANDCLK='1'THEN
IFSTO='1'THENSTATE:
="00";CQI:
=CQI;--暂停
ELSIFENABLE='1'THEN
CQI:
=CQI+1;
IFCQI<=30THENSTATE:
="01";--小于3公里
ELSIFCQI>30ANDCQI<=90THENSTATE:
="10";--大于3公里小于9公里
ELSE
STATE:
="11";--大于9公里
ENDIF;
ENDIF;
ENDIF;
ST<=STATE;
ENDPROCESS;
ENDONE;
三、计费模块源代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYjifeiIS--计费模块
PORT(CLK_DIV:
INSTD_LOGIC;
CLR1:
INSTD_LOGIC;--清零信号
ST2:
INSTD_LOGIC;
ENABLE2:
INSTD_LOGIC;
SI:
INSTD_LOGIC_VECTOR(1DOWNTO0);--计费模式选择信号
C1:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
2:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
C3:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
C4:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));--以上4位为车费的四位显示
ENDjifei;
ARCHITECTUREONEOFjifeiIS
BEGIN
PROCESS(CLK_DIV,CLR1,SI,ENABLE2,ST2)
VARIABLEQ1:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ2:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ3:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ4:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IFCLR1='0'THENQ1:
="0000";Q2:
="0000";Q3:
="0000";Q4:
="0000";--清零
ELSIFCLK_DIV'EVENTANDCLK_DIV='1'THEN
IFST2='1'THENQ1:
=Q1;Q2:
=Q2;Q3:
=Q3;Q4:
=Q4;--如果停止,保持原来路程
ELSIFENABLE2='1'THEN--计费使能信号
CASESIIS
WHEN"00"=>Q1:
=Q1;Q2:
=Q2;Q3:
=Q3;Q4:
=Q4;--停止状态时,车费保持不变
WHEN"01"=>Q1:
="0000";Q2:
="0111";Q3:
="0000";Q4:
="0000";--小于3公里时显示007.0元
WHEN"10"=>IFQ1<"1000"THEN--大于3公里小于9公里时车费各位显示
Q1:
=Q1+2;--每来一个脉冲,相当于前进1公里,车费加2.2元
IFQ2<"1000"THEN
Q2:
=Q2+2;
ELSEQ2:
=Q2-8;
IFQ3<"1001"THEN
Q3:
=Q3+1;
ELSEQ3:
="0000";
IFQ4<"1001"THEN
Q4:
=Q4+1;
ELSEQ4:
="0000";
ENDIF;
ENDIF;
ENDIF;
ELSE
Q1:
="0000";
IFQ2<"0111"THEN
Q2:
=Q2+3;
ELSEQ2:
=Q2-7;
IFQ3<"1001"THEN
Q3:
=Q3+1;
ELSEQ3:
="0000";
IFQ4<"1001"THEN
Q4:
=Q4+1;
ELSEQ4:
="0000";
ENDIF;
ENDIF;
ENDIF;
ENDIF;
WHEN"11"=>IFQ1<"0111"THEN--车程大于9公里时车费各位显示,每来一个脉冲,车费加3.3元
Q1:
=Q1+3;
IFQ2<"0111"THEN
Q2:
=Q2+3;
ELSEQ2:
=Q2-7;
IFQ3<"1001"THEN
Q3:
=Q3+1;
ELSEQ3:
="0000";
IFQ4<"1001"THEN
Q4:
=Q4+1;
ELSEQ4:
="0000";
ENDIF;
ENDIF;
ENDIF;
ELSE
Q1:
=Q1-7;
IFQ2<"0101"THEN
Q2:
=Q2+4;
ELSEQ2:
=Q2-6;
IFQ3<"1001"THEN
Q3:
=Q3+1;
ELSEQ3:
="0000";
IFQ4<"1001"THEN
Q4:
=Q4+1;
ELSEQ4:
="0000";
ENDIF;
ENDIF;
ENDIF;
ENDIF;
WHENOTHERS=>NULL;
ENDCASE;
ENDIF;
ENDIF;
C1<=Q1;
C2<=Q2;
C3<=Q3;
C4<=Q4;
ENDPROCESS;
ENDONE;
四、计程模块源代码
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYjichenIS--计算路程的模块
PORT(CLK_CLK:
INSTD_LOGIC;--一个脉冲来相当于走了0.1公里
CLR2:
INSTD_LOGIC;--清零信号
ST1:
INSTD_LOGIC;
ENABLE1:
INSTD_LOGIC;
C5:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
C6:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
C7:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
C8:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));--以上4位为路程的四位显示位
ENDjichen;
ARCHITECTUREONEOFjichenIS
BEGIN
PROCESS(CLK_CLK,CLR2,ST1,ENABLE1)
VARIABLEQ5:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ6:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ7:
STD_LOGIC_VECTOR(3DOWNTO0);
VARIABLEQ8:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IFCLR2='0'THENQ5:
="0000";Q6:
="0000";Q7:
="0000";Q8:
="0000";
ELSIFCLK_CLK'EVENTANDCLK_CLK='1'THEN
IFST1='1'THENQ5:
=Q5;Q6:
=Q6;Q7:
=Q7;Q8:
=Q8;--如果停止,保持原来路程
ELSIFENABLE1='1'THEN--计费使能信号
IFQ5<"1001"THEN
Q5:
=Q5+1;--来一个时钟,路程加0,1公里
ELSE
Q5:
="0000";
IFQ6<"1001"THEN
Q6:
=Q6+1;
ELSE
Q6:
="0000";
IFQ7<"1001"THEN
Q7:
=Q7+1;
ELSE
Q7:
="0000";
IFQ8<"1001"THEN
Q8:
=Q8+1;
ENDIF;
ENDIF;
ENDIF;
ENDIF;
ENDIF;
ENDIF;
C5<=Q5;
C6<=Q6;
C7<=Q7;
C8<=Q8;
ENDPROCESS;
ENDONE;
五、显示模块源代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYdisplayIS--8位数码管动态显示模块
PORT(DI1:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI2:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI3:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI4:
INSTD_LOGIC_VECTOR(3DOWNTO0);--以上四位为车费
DI5:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI6:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI7:
INSTD_LOGIC_VECTOR(3DOWNTO0);
DI8:
INSTD_LOGIC_VECTOR(3DOWNTO0);--以上四位为路程
CLK2:
INSTD_LOGIC;
SG:
OUTSTD_LOGIC_VECTOR(6DOWNTO