出租车的FPGA设计Word格式文档下载.docx
《出租车的FPGA设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《出租车的FPGA设计Word格式文档下载.docx(25页珍藏版)》请在冰豆网上搜索。
![出租车的FPGA设计Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2023-2/4/1268a8e7-9b94-48f5-9a80-f3ed0abfd22c/1268a8e7-9b94-48f5-9a80-f3ed0abfd22c1.gif)
附录(源代码)
1.方案比较与选择
1.1方案一
图1出租车计费器方案一原理框图
1.1.1出租车计费器方案一原理
基于FPGA设计的出租车计费器系统如图1所示,各模块功能如下:
(1)计费电路:
该电路主要有4个输入端口:
时钟信号、启动、停止、暂停;
两个输出端口:
路费端口和路程端口,并将数据输出给数据转换模块。
(2)数据转换:
将路费和里程的整数表示分离为四位十进制数表示,计费器的两个输出端口作为该电路的输入口,即两个输入信号为路费和里程,输出信号则为经过转换后的路费和里程。
(3)显示电路:
接收来自数据转换模块的8组数据,并用一个3选8数据选择器动态将数据输送至数码管显示。
同时设置一个输出端口接到实验箱上的74LS138的S1、S2、S3口,使数据输出到8个对应的端口。
(4)选择信号产生电路:
控制路费和里程的八位输出顺序。
(5)译码电路:
把二进制码译成7段数码管显示。
(6)显示模块:
显示模块采用的是共阴极数码管,根据十六进制数和七段显示段码表的对应关系,其中要求路程和车费都用一位小数点来表示,所以须要设置一个控制小数点的变量,即程序中的x。
这段程序所示的是在数码管的第二、六个数码管后面的显示小数点,实现了路程和车费都用1位小数点表示的功能,如果选择的扫描频率不合适,可能会出现小数点闪动的情况。
但只要扫描频率不少于24HZ,人眼就感觉不到数码管的闪烁。
数码管控制及译码显示模块将BCD信号的输入用七段数码管显示,由七段发光二极管组成数码显示,利用字段的不同组合,可表示0-9十个数字。
1.1.2方案一的可行性
方案一基本可以实现计费功能,在原件设计上也容易实现,但是存在计费模块和选择模块共用相同时钟脉冲的缺陷。
1.2方案二
扫描时钟
时钟脉冲
图2出租车计费器方案二原理框图
1.2.1出租车计费器方案二可行性
方案二与方案一基本原理大致相同,也分为计程,进制转换,显示,选择,译码五个电路模块,区别在于完善了原方案在选择模块与计程电路模块上共用同一时钟信号导致的不足,因为数码管动态扫描需要较高的时钟频率,而如果计程模块的输入脉冲信号过高则不利进制转换模块对计程模块输出的转换,且不便于实验演示,更进一步完善了原方案的精度,使方案二的计费器的路程精确到50米,费用精确到1.1角(演示时因数码管位数不足则略去分位)
2.底层文件仿真与分析
2.1出租车计费器系统模块连接图
图3出租车计费器系统电路
2.1.1计程模块仿真
其中,clk1表示车轮每转一圈来一个脉冲,star_rst为启动复位信号,pause为暂停信号。
但为方便观察,现将jicheng模块一些变量改小,从下图可看出当
当车程在3公里内时车费保持7元不变;
当车程大于3公里小于9公里时,当lucheng1在0和5变化时相当于车前进了50米,即车费要加0.11元此时chefei一直是加11;
当车程大于9公里lucheng1在0和5变化时车费要轮流加0.16和0.17元,此时chefei变为轮流加16和17。
总路程小于3km时仿真截图
总路程大于9km时仿真截图
同时由第二幅图可以看出当pause信号有效即使clk1还有脉冲过来时路程和车费确实有暂停。
2.1.2进制转换模块分析及仿真
其中LL1~LL4为路程装换后的各位输出,依次为百分、十分、个、十位(因数码管个数有限,在此屏蔽了路程百位进制装换后的输出),CC1~CC4为车费装换后的各位输出,依次为十分、个、十、百位。
例如:
整数2012的个位、十位、百位、千位可以分别表示为:
0010、0001、0000、0010。
转换目的:
方便译码电路译码。
但因为输入信号lucheng1、lucheng2、chefei均为整数型数据,无法创建输入信号,所以未给出此模块的仿真波形图。
2.1.3显示模块分析及仿真
采用8位动态扫描显示车费和车程,其中是CC1-CC4计费输入,是LL1-LL4里程输入,xunaze信号控制选择LL1~LL4、CC1~CC4中的一位赋给data。
如图:
当xuanze信号为000时选择CC1"
1000"
并在低位并0输给data,此时data为"
10000"
当xuanze信号为001时选择CC2"
0100"
并在低位并1输给data,并1表示该位加了小数点,其它情况同理,仿真如下图所示:
2.1.4选择模块分析及仿真
通过xuanze信号输出“000”-“111”的循环信号,控制路费和里程的八位输出顺序并产生74LS138的三个输入信号s0、s1和s2。
仿真波形如下图所示:
选择信号产生电路仿真
2.1.5译码模块分析及仿真
把二进制码译成7段数码管显示,例如数码管译码为“011111110”显示“0”,数码管译码为“111111110”显示“0.”。
如下图所示。
数码管译码电路仿真
3.顶层文件仿真与分析
顶层文件有四个输入端口,分别是clk1车轮转圈脉冲,clk2其他模块工作时钟,star_rst启动复位信号,高电平开始计费用及里程,低电平复位;
pause为暂停信号,高电平有效;
chefei为车费输出,lucdheng1为总路程小于1KM的路程输出,lucheng2为总路程大于1KM的路程输出。
当lucheng2小于3KM时车费一直输出为700,表示7元,当lucheng1由0变5时表示总路程变为3.05KM,此时chefei为711,表示加了0.11元。
如下图:
当lucheng2等于9且lucheng1等于0时车费输出为2020,表示20.2元,前面加价准确
顶层文件仿真图
当start_rst信号由1变0时chefei跟lucheng1、lucheng2进行复位显示,车费显示起步价700,总路程变为0,如图所示:
4.硬件验证分析
程序代码在MAXPLUSII成功编写和仿真完毕,拷入FPGA,涉及步骤及相关问题的解决如下:
(1)安装FPGA实验箱驱动;
(2)在配置的时候,应该注意3.sof文件用于利用编程电缆ByteBlaster进行配置.而3.pof用于配置EPROM.(EPROM只能写入一次),所以在设计的时候,线可用编程电缆调试无误后,在写入EPROM中.
(3)代码下载成功后,数码管不能显示。
问题在于把数码管的引脚在显示模块设置,而真正应该下载到实验箱的代码是顶层模块。
正确是将端口设置全部设置在顶层模块中。
(4)在动态扫描中,小数点设置成了动态扫描的障碍。
解决方法是,将DP独立设置一位,不需要动态扫描。
因为小数点是不变的。
计费与里程的时钟不同步,导致计费和里程显示不同步。
出现,里程显示不变化,而计费开始。
(5)当使能信号开始时,并非显示00.00070.0,有乱码出现的情况,解决方法是检查和修改初始代码。
5.课程设计心得
本次课程设计要求我们运用应用EDA课程上学习的理论知识及平时实验课程上的积累经验,运用层次化的设计方法设计一个简单的出租车计费器电路,能够模拟实现出租车启动、停止、暂停计费,计程等基本功能。
根据功能电路原理图,我们在设计软件QUARTUSII上,首先运用VDHL编写了计费器的各个模块及顶层文件的程序代码,并分别成功编译和仿真,最终在试验箱能够得到正常的出租车计费器的模拟运行结果。
通过此次课程设计,我们对VHDL设计语言以及用VHDL进行功能模块的程序设计有了更加切实而深刻的感受。
编制程序过程中遇到的一系列问题在考验了我们理论结合实际的应变能力同时,也帮我们积累了弥足珍贵的功能电路设计经验,为以后进行更多更复杂的编程设计打下了一定的操作基础。
除了专业知识与技能的锻炼和提升,本次设计也考验了我们小组成员的团队协作能力,增进了彼此的配合。
总而言之,虽然只是一次简短的课程设计,却让我们收获了许多不可或缺的知识与技能。
参考文献
[1].潘松,黄继业.EDA技术实用教程.科学出版社.2005.2:
145~156.
[2].候伯亨,顾新.VHDL硬件描述语言与数字逻辑电路设计.西安电子科技大学.2004.11:
45~48.
[3]廖艳秋.基于FPGA的出租车计费器设计[D].成都:
电子科技大学,2008.
[4]焦敏.FPGA在出租车计费器上的应用研究[J].中国科技信息,2009(9):
145-146.
JIAOMin.ResearchoftaximeterbasedonFPEA[J].ChinaScienceandTechnologyInformation,2009(9):
[5]刘欲晓,方强,黄宛宁.EDA技术与VHDL电路开发应用实践[M].北京:
电子工业出版社,2009,175-186.
[6]StephenBrown,ZvonkoVranesic.数字逻辑基础与VHDL设计[M].3版.北京:
清华大学出版社,2011.
附录(源代码)
1、计程模块
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityjichengis
port(clkl,start_rst,pause:
instd_logic;
endjicheng;
architectureabcdofjichengis
begin
process(clkl,start_rst,pause)
variablea:
integerrange0to27;
variableb:
integerrange0to2;
variablefy,lc1,lc2:
integerrange0to99999;
chefei,lucheng1,lucheng2begin
if(clkl'
eventandclkl='
1'
)then
if(start_rst='
0'
)then
a:
=0;
b:
fy:
=700;
lc1:
lc2:
elsif(start_rst='
andpause='
=a+1;
if(a=27)then
=lc1+5;
if(lc1=100)then
=lc2+1;
endif;
if(lc2<
3)then
elsif(lc2=3andlc1>
4)or(lc2>
=4andlc2<
9)then
=fy+11;
elsif(lc2=9andlc1=0)then
elsif(lc2=9andlc1>
4)or(lc2>
9)then
=fy+16;
=b+1;
if(b=2)then
=fy+1;
=a;
=b;
chefei<
=fy;
lucheng1<
=lc1;
lucheng2<
=lc2;
endprocess;
endabcd;
2、进制转换模块
entityjinzhiis
port(clk2:
lucheng1,lucheng2,chefei:
inintegerrange0to99999;
LL1,LL2,LL3,LL4,CC1,CC2,CC3,CC4:
outstd_logic_vector(3downto0));
endjinzhi;
architectureabcdofjinzhiis
process(clk2,chefei)
variablec:
variableca,cbb,cc,cd,ce:
std_logic_vector(3downto0);
--,cff
if(clk2'
eventandclk2='
if(c<
chefei)then
if(ca=9andcbb=9andcc=9andcd=9)then
ca:
="
0000"
;
cbb:
cc:
cd:
ce:
=ce+1;
c:
=c+1;
elsif(ca=9andcbb=9andcc=9)then
=cd+1;
elsif(ca=9andcbb=9)then
=cc+1;
elsif(ca=9)then
=cbb+1;
else
=ca+1;
else
CC1<
=cbb;
CC2<
=cc;
CC3<
=cd;
CC4<
=ce;
process(clk2,lucheng1)
variablelc1:
variablela,lbb:
if(lc1<
lucheng1)then
if(la=9)then
la:
lbb:
=lbb+1;
=lc1+1;
=la+1;
LL1<
=la;
LL2<
=lbb;
process(clk2,lucheng2)
variablelc2:
variablelc,ld,le:
lucheng2)then
if(lc=9andld=9)then
lc:
ld:
le:
=le+1;
elsif(lc=9)then
=ld+1;
=lc+1;
LL3<
=lc;
LL4<
=ld;
3、显示模块
entityxianshiis
port(xuanze:
instd_logic_vector(2downto0);
LL1,LL2,LL3,LL4,CC1,CC2,CC3,CC4:
instd_logic_vector(3downto0);
data:
outstd_logic_vector(4downto0));
endxianshi;
architectureabcdofxianshiis
withxuanzeselect
data<
=CC1&
'
when"
000"
CC2&
001"
CC3&
010"
CC4&
011"
LL1&
100"
LL2&
101"
LL3&
110"
LL4&
whenothers;
4、选择信号模块
entityxuanzeis
s0,s1,s2:
outstd_logic;
xuanze:
outstd_logic_vector(2downto0));
endxuanze;
architectureabcdofxuanzeis
process(clk2)
variablexz:
std_logic_vector(2downto0);
if(xz<
"
111"
xz:
=xz+1;
xuanze<
=xz;
s0<
=xz(0);
s1<
=xz
(1);
s2<
=xz
(2);
5、译码模块
entityyimais
port(data:
instd_logic_vector(4downto0);
q:
outstd_logic_vector(7downto0));
endyima;
architectureabcdofyimais
process(data)
casedatais
when"
00000"
=>
q<
01111110"
00001"
11111110"
00010"
00110000"
00011"
10110000"
00100"
01101101"
00101