课程设计基于FPGA的出租车计价器设计.doc
基于FPGA的出租车计价器设计摘 要介绍了出租车计费器系统的组成及工作原理,简述了在EDA平台上用FPGA器件构成该数字系统的设计思想和实现过程。论述了计程模块,计费模块,计时模块,译码动态扫描模块等的设计方法与技巧。 1引言随着EDA技术的高速发展,电子系统的设计技术发生了深刻的变化,大规模可编程逻辑器件CPLDFPGA的出现,给设计人员带来了诸多方便。利用它进行产品开发,不仅成本低、周期短、可靠性高,而且具有完全的知识产权。本文介绍了一个以Altera公司可编程逻辑芯片cyclone2系列的EP2C5T144C8的FPGA芯片为控制核心、附加一定外围电路组成的出租车计费器系统。随着社会的不断进步,人们生活水平的不断提高,出租车逐渐成为人们日常生活不可缺少的交通工具。而计价器作为出租车的一个重要组成部分,关系着出租车司机和乘客双方利益,起着重要的作用,因而出租车计价器的发展非常迅猛。2出租车计费系统的实验任务及要求2.1技术要求(1)掌握较复杂逻辑的设计、调试。(2)进一步掌握用VHDL语言设计数字逻辑电路。(3)掌握用Max+pulsII软件的原理图输入的设计方法。2.2功能要求基本功能:(1)按行驶里程收费,起步价为9.00元,并在车行3公里后再按3元/公里计算车费。(2)实现模拟功能:能模拟汽车启动、停止。(3)设计动态扫描电路:将车费、里程、等待时间动态的显示出来。(4)用VHDL语言设计符合上述功能要求的出租车计费器,并用层次化设计方法设计该电路。(5)各计数器的计数状态用功能仿真的方法验证,并通过有关波形确认电路设计是否正确。附加功能:(1)增加了晚上计费功能和等待功能。晚上起步价为12.00元,并在车行3公里后再按4元/公里计算车费。车白天停止超过三分钟后按1元/分钟计算,晚上超过3分钟按2元/分钟计算。(2)实现预置功能:能预置起步费、每公里收费、等待加费时间。(3)实现模拟功能:白天、黑夜;等待、行驶状态。(4)设计超过三公里提醒功能。2.3本人任务本人负责软件部分。2.4任务书(附录一)3.方案设计及原理框图3.1硬件方案设计及原理框图硬件系统组成框图开关电路FPGA模块动态显示电路各模块的作用和组成:(1)开关模块该模块的作用是用于电路的输入的信号。主要有三个开关以及三个限流电阻,电源构成。(3)动态显示模块:此模块由六个数码管和三个二极管所构成,17个200电阻起到限制电流的作用,使得流到数码管的电流适当,防止数码管中的电流过大,而使得数码管损坏。数码管将计费、等待时间和里程动态的显示出来。3.2软件方案设计及原理框图3.2.1系统的顶层框图及方案设计:动态显示模块控制芯片信号输入 信号输入:各种控制信号经输入端给控制芯片。控制芯片:采用的有CPLD或者FPGA等。动态显示电路:采用的是数码管来实现功能的输出。3.2.2 FPGA内部具体框图及方案设计:出租车的一般计费过程为:出租车载客后,启动计费器,整个系统开始运行,里程计数器从0开始计数,费用计数器从9开始计算;出租车载客中途等待,等待时间计数器从0开始计数。最后根据行驶里程或停止等待的时间的计费标准计费。出租车到达目的地停止后,停止计费器,显示总费用。根据出租车计费器的工作过程,本系统采用分层次、分模块的方式设计,其FPGA内部具体框图如下所示。输入信号分频器车费计数模块车行驶状态译码模块输出控制模块里程计数模块各模块的功能:(1)由FPGA晶振电路产生50MHz时钟信号并输入。(2)分频器:将时钟信号进行分频。(3)标志模块:将按钮产生的脉冲转化为一种标志信号。(4)计程模块:在等待信号未作用时,来一个时钟脉冲信号,里程值加1。该模块还包含一个路程计费标志的小模块,输出一个路程计费的信号。(5)等待状态模块:等待信号作用时,该模块可以记录等待的时间,并产生等待计费的信号。(6)车费计数模块:按行驶里程收费,分为白天和黑夜。白天收费标准:起步费为12.00元,超过3公里按4元/公里,车暂停超过三分钟按2元/分钟计算。黑夜收费标准:起步费为15.00元,超过3公里按5元/公里,车暂停超过三分钟按1元/分钟计算。(7)输出控制模块:分时输出里程、等待时间、费用三个信号,实现动态显示功能。(8)译码模块:实现将车费计数模块、等待状态模块和里程计数模块输出的BCD码转换成七段码输出。4.各单元模块设计,仿真结果及分析本系统采用层次化、模块化的设计方法,设计顺序为自下向上。首先实现系统框图中的各子模块,然后由顶层模块调用各子模块来完成整个系统。4.1分频模块:4.1.1分频模块的框图图3.1.1分频器的实体图此模块的功能是对总的时钟进行分频,总的时钟是50M。计数分频器使用五个这样基本的分频器(35分频)组合而成,控制模块分频器使用三个这样基本的分频器(35分频)组合而成。4.1.2分频模块的VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY PULSE IS PORT(CLK0:IN STD_LOGIC; FOUT:OUT STD_LOGIC);END PULSE;ARCHITECTURE ONE OF PULSE ISBEGIN PROCESS(CLK0) VARIABLE CNT:STD_LOGIC_VECTOR(2 DOWNTO 0); VARIABLE FULL :STD_LOGIC; BEGIN IF CLK0'EVENT AND CLK0='1' THEN IF CNT="100" THEN CNT:="000" ; FULL:='1' ELSE CNT:=CNT+1; FULL:='0' END IF; END IF;FOUT<=FULL;END PROCESS;END ONE;4.1.3仿真的结果从该波形图可以看出输入脉冲的频率是输出脉冲的频率的35倍。4.2计程模块:4.2.1计程模块的框图:此模块的功能是计算出租车行驶的路程。在出租车启动并行驶的过程中(开始/结束信号SS为1,行驶/等待信号WR为1),当时钟clks是上升沿的时候,系统即对路程计数器JC的里程计数器进行加计数,当路程超过三公里时,系统将输出标志正脉冲LCJFBZ。4.2.2计程模块的VHDL程序(1) 计程程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity JC is port(clks,SS,WR:in std_logic; LC:BUFFER std_logic_vector(7 downto 0); end entity JC;architecture one of JC is SIGNAL Q1,Q0:std_logic_vector(3 downto 0);beginprocess(clks,SS,WR,LC) VARIABLE SW:STD_LOGIC_VECTOR(1 DOWNTO 0); begin SW:=SS&WR; IF SW="00" OR SW="01" THEN Q1<="0000"Q0<="0000" ELSIF SW="11" THEN Q1<=Q1;Q0<=Q0; ELSIF CLKS'EVENT AND CLKS='1' THEN IF Q1=9 AND Q0=9 THEN Q1<="0000"Q0<="0000" ELSIF Q0=9 THEN Q1<=Q1+1;Q0<="0000" ELSE Q1<=Q1;Q0<=Q0+1; END IF; END IF;END PROCESS;(2) 计程标志程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity LCJFBZ is port(SS:in std_logic; -SS开始/复位信号, LC:IN STD_LOGIC_VECTOR(7 DOWNTO 0); LCJFBZ:OUT std_logic); end entity LCJFBZ;architecture TWO of LCJFBZ is BEGIN PROCESS(SS,LC) BEGIN IF SS='0' OR (LC(7 DOWNTO 4)="0000" AND LC(3 DOWNTO 0)<4) THEN LCJFBZ<='0' ELSE LCJFBZ<='1' END IF; END PROCESS;END TWO;4.2.3计程模块仿真结果:从波形图可以看出在时钟的控制下当SS为低电平的时候LC为零,当SS为高电平且WR为高电平的时候LC开始计数,当计到大于三的时候输出了LCJFBZ为高电平。4.3计时模块:4.3.1计时模块的框图:此模块用于计算停车等待的时间。在出租车行进中,如果车辆停止等待,计数器则在信号clk的上升沿进行加计数,当累计等待时间超过2(不包括2分钟)分钟时,输出标志DDJFBZ正脉冲信号。4.3.2计时模块的VHDL程序:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY DDZT IS PORT(CLK,SS:IN STD_LOGIC; DDBZ:IN STD_LOGIC; DDJFBZ:OUT STD_LOGIC; DDSJ:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);END ENTITY DDZT;ARCHITECTURE ONE OF DDZT ISBEGIN PROCESS(CLK,SS,DDBZ) VARIABLE Q1,Q0: STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN IF SS='0' THEN Q1:="0000"Q0:="0000"DDJFBZ<='0' ELSIF DDBZ='1' THEN IF CLK='1' AND CLK'EVENT THEN IF Q1=9 AND Q0=9 THEN Q1:="0000"Q0:="0000" ELSIF Q0=9 THEN Q1:=Q1+1;Q0:="0000" ELSE Q1:=Q1;Q0:=Q0+1; END IF; IF(Q1>0 OR Q0>3) THEN DDJFBZ<='1' END IF; END IF; END IF; DDSJ(7 DOWNTO 4)<=Q1;DDSJ(3 DOWNTO 0)<=Q0;END PROCESS;END ONE;4.3.3计时模块的仿真结果:从波形图可以看出在clk的控制下当SS为高电平DDBZ为高电平的时候时间计数但是费用没有计数,DDJFBZ为低电平。4.4计费模块:4.4.1计费模块的框图:费用计数器模块用于出租车启动后,根据行驶路程和等待时间计算费用。当出租车启动时,SS为高电平,用于将费用计数器复位为起步价10元;当车处于行驶状态且满3公里时,select_clk信号选择distans_enable,此后路程每满1公里,费用计数器加1元;当出租车处于停止等待状态且时钟满2分钟时,select_clk信号选择time_enable信号,时间每满1分钟,费用计数器加1元。4.4.2计费模块的VHDL的程序:library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;-定义函数名PACKAGE PACKEXP1 IS FUNCTION bcd_add8(AIN,BIN : in std_logic_vector) RETURN std_logic_vector;END;-描述函数体PACKAGE BODY PACKEXP1 IS FUNCTION bcd_add8(AIN,BIN : std_logic_vector) RETURN std_logic_vector IS type type_bcdx4 is array(3 downto 0) of std_logic_vector(4 downto 0); VARIABLE SA,SB : type_bcdx4; VARIABLE CI : std_logic_vector(4 downto 0); VARIABLE SOUT : std_logic_vector(11 downto 0); BEGIN CI:=(others=>'0'); SOUT:=(others=>'0'); for i in 0 to 1 loop -0-1的循环 SA(i) := ('0' & AIN(i*4+3 downto i*4)+('0' & BIN(i*4+3 downto i*4)+("0000" & CI(i); if (SA(i)(4)='1') or (SA(i)(3 downto 0)>9) then SB(i) := SA(i) + "00110" else SB(i) := SA(i); end if; CI(i+1) := SB(i)(4); SOUT(i*4+4 downto i*4):=SB(i); end loop; RETURN SOUT;END FUNCTION bcd_add8;END;library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;USE WORK.PACKEXP1.ALL;ENTITY JF is PORT( SS:IN STD_LOGIC; -开始/停止信号,低电平停止,高电平开始 DN:IN STD_LOGIC; -白天黑夜控制,高电平夜间,低电平白天 LC:IN std_logic_vector(7 downto 0); - 路程 DDSJ:IN STD_LOGIC_VECTOR(7 DOWNTO 0); -等待时间 LCJFBZ:IN STD_LOGIC; -路程计费标志 DDJFBZ:IN STD_LOGIC; -等待计费标志,高电平时等待开始计费,低电平不计费 FY:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -总费用END ENTITY JF;architecture ONE of JF is BEGIN - 讨论白天/黑夜?路程计费?等待计费? PROCESS(SS,DN,LC,DDSJ,DDJFBZ,LCJFBZ) VARIABLE FY1 :STD_LOGIC_VECTOR(11 DOWNTO 0); BEGIN IF SS='0' THEN FY1:="000000000000" ELSIF DN='0' THEN -白天时 IF LCJFBZ='0' THEN -起始价 FY1(11 DOWNTO 4):=(OTHERS=>'0'); -9 FY1(3 DOWNTO 0):="1001" ELSE -加收路程费 FY1:=bcd_add8(LC,LC); FY1:=bcd_add8(FY1,LC); -多一个脉冲加收3,则变成LC*3 END IF; ELSIF LCJFBZ='0' THEN -起始价 FY1(11 DOWNTO 5):=(OTHERS=>'0'); FY1(4 DOWNTO 0):="10010" -12 ELSE FY1:=bcd_add8(LC,LC); FY1:=bcd_add8(FY1,LC); FY1:=bcd_add8(FY1,LC); -每一个脉冲加收4,则变成LC*4 END IF; IF DN='0' THEN -白天时 IF DDJFBZ='0' THEN -未到等待收费时间 FY1:=FY1; -不加收 ELSE -加收路程费 FY1:=bcd_add8(FY1,DDSJ); FY1:=bcd_add8(FY1,DDSJ); -一超过等待收费时间,就立即加收等待时的每个脉冲加2 END IF; ELSIF DDJFBZ='0' THEN -未到等待收费时间 FY1:=FY1; -不加收 ELSE -加收路程费 FY1:=bcd_add8(FY1,DDSJ); -一超过等待收费时间,就立即加收等待时的每个脉冲加1 END IF; FY<=FY1(7 DOWNTO 0); END PROCESS;END ONE;4.4.3计费模块的仿真结果:白天模式黑夜模式从波形图可以看出DN为高电平选择白天模式进行计费,DN为低电平选择黑夜模式进行计费。4.5数码管显示模块:4.5.1数码管显示模块的框图:4.5.2数码管显示的VHDL程序:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity YMQ isport(din:in std_logic_vector(7 downto 0); dout1:out std_logic_vector(6 downto 0); dout0:out std_logic_vector(6 downto 0);end entity YMQ;architecture one of YMQ isbeginprocess(din)begin case din(7 downto 4) is when "0000" =>dout1<="1111110" when "0001" =>dout1<="0110000" when "0010" =>dout1<="1101101" when "0011" =>dout1<="1111001" when "0100" =>dout1<="0110011" when "0101" =>dout1<="1011011" when "0110" =>dout1<="1011111" when "0111" =>dout1<="1110000" when "1000" =>dout1<="1111111" when "1001" =>dout1<="1111011" when others =>dout1<="0000000"end case; case din(3 downto 0) is when "0000" =>dout0<="1111110" when "0001" =>dout0<="0110000" when "0010" =>dout0<="1101101" when "0011" =>dout0<="1111001" when "0100" =>dout0<="0110011" when "0101" =>dout0<="1011011" when "0110" =>dout0<="1011111" when "0111" =>dout0<="1110000" when "1000" =>dout0<="1111111" when "1001" =>dout0<="1111011" when others =>dout0<="0000000"end case;end process;end one;4.5.3数码管显示模块的仿真结果:4.6控制模块:4.6.1控制模块的框图:控制模块用于对数码管里程、时间、费用显示的选择,起到位选的作用,实现了数码管动态显示,节省了芯片的资源。4.6.2控制模块的VHDL程序:(1)sel1模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity sel1 is port(clk1:in std_logic; s1:out std_logic_vector(1 downto 0);end sel1;architecture sel_arc of sel1 isbegin process(clk1) variable cnt:std_logic_vector(1 downto 0);begin if clk1'event and clk1='1' then IF cnt="10" then cnt:="00" else cnt:=cnt+1; end if; end if;s1<=cnt;end process;end sel_arc;(2)sel2模块library ieee;use ieee.std_logic_1164.all;entity sel2 isport(sel2:in std_logic_vector(1 downto 0); s2:out std_logic_vector(2 downto 0);end sel2;architecture bbb_arc of sel2 isbegin process(sel2)begincase sel2 is when "00"=>s2<="110" when "01"=>s2<="101" when "10"=>s2<="011" when others=>s2<="ZZZ"end case;end process;end bbb_arc;4.6.3控制模块的仿真结果:(1)sel1模块(2)sel2模块从波形图可以看出当片选信号是00时,输出选择记程输出。当片选信号是01时,输出选择记费输出。当片选信号是10时,输出选择等到时间输出。5.顶层模块设计,仿真结果及分析各模块设计仿真实现后,可分别创建成元件符号。顶层就是将各分模块用VHDL语言或者是图形方法连接起来,便可实现系统电路。5.1顶层模块的VHDL程序:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity czc isport(clk,wr,ss,dn:in std_logic; dnpd:out std_logic; shuc1,shuc0:out std_logic_vector(6 downto 0); weix:out std_logic_vector(2 downto 0);end entity czc;architecture one of czc iscomponent bzPORT(AJ:IN STD_LOGIC; BZ:OUT STD_LOGIC);end component;component pulse PORT(CLK0:IN STD_LOGIC; FOUT:OUT STD_LOGIC);end component;component ddzt PORT(CLK,SS:IN STD_LOGIC; DDBZ:IN STD_LOGIC; DDJFBZ:OUT STD_LOGIC; DDSJ:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);end component;component jcport(clks,SS,WR:in std_logic; LC:BUFFER std_logic_vector(7 downto 0);待添加的隐藏文字内容1end component;component lcjfbzport(SS:in std_logic; LC:IN STD_LOGIC_VECTOR(7 DOWNTO 0); LCJFBZ:OUT std_logic); end component;component jf PORT( SS:IN STD_LOGIC; DN:IN STD_LOGIC; LC:IN std_logic_vector(7 downto 0); DDSJ:IN STD_LOGIC_VECTOR(7 DOWNTO 0); LCJFBZ:IN STD_LOGIC; DDJFBZ:IN STD_LOGIC; FY:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); end component;component ymqport(din:in std_logic_vector(7 downto 0); dout1:out std_logic_vector(6 downto 0); dout0:out std_logic_vector(6 downto 0);end component;component xzscport(jc,jf,wt:in std_logic_vector(7 downto 0);sel:in std_logic_vector(1 downto 0);q:out std_logic_vector(7 downto 0);end component;component sel1port(clk1:in std_logic;s1:out std_logic_vector(1 downto 0);end component;component sel2port(sel2:in std_logic_vector(1 downto 0);s2:out std_logic_vector(2 downto 0);end component;signal a,b,c,d,e,f,i,j,m,n:std_logic;signal x,y,z,W:std_logic_vector(7 downto 0);signal k:std_logic_vector(1 downto 0); begindnpd<=a;u1:bz port map(aj=>dn,bz=>a);u2:bz port map(aj=>ss,bz=>b);u3:bz port map(aj=>wr,bz=>c);u4:pulse port map(clk0=>clk,fout=>d);u5:pulse port map(clk0=>d,fout=>i);u6:pulse port map(clk0=>i,fout=>j);u7:pulse port map(clk0=>j,fout=>m);u8:pulse port map(clk0=>m,fout=>n);u9:jc port map(clks=>n,ss=>b,wr=>c,lc=>z);u10:ddzt port map(clk=>n,ss=>b,ddbz=>c,ddjfbz=>f,ddsj=>y);u11:lcjfbz port map(ss=>b,lc=>z,lcjfbz=>e);u12:jf port map(ss=>b,dn=>a,lc=>z,ddsj=>y,lcjfbz=>e,ddjfbz=>f,fy=>x);u13:xzsc port map(jf=>x,jc=>z,wt=>y,sel=>k,q=>W);u14:sel1 port map(clk1=>j,s1=>K);u15:sel2 port map(sel2=>K,s2=>weix);u16:ymq port map(din=>W,dout1=>shuc1,dout0=>shuc0);end architecture one;5.2波形仿真5.3输入、输出信号说明输入:DN:day OR night控制;SS:Start OR stop控制;WR:wait OR run控制;CLK:输入时钟信号,模拟时间和路程。输出:DNPB:用于判别白天还是黑夜的输出信号,接至发光二极管,白天不发光,黑夜的时候发光。FY1:费用的十位FY0:费用的个位DDSJ1:等待时间的十位DDSJ0:等待时间的个位LC1:路程的十位LC0:路程的个位5.4各个模块的软件连线图(见附录二)6硬件电路设计与安装图6.1硬件电路设计图(见附录三)6.2硬件电路的元器件清单:器件名称及个数杜邦线若干根电阻200欧姆21个1K3个20脚底座3个插针若干个90123个发光二极管1个数码管6个按钮开关3个芯片FPGA导线若干根7硬件电路安装与调试7.1硬件电路安装与调试的步骤(1)根据硬件电路图在通用板上布线(2)检查元器件的好坏,确保每一个元器件是好的才能进行焊接(焊接时要注意虚焊,短路等等)(3)焊好之后要根据安装图用万用表进行测量,防止电路存在错误(注意焊接要仔细)7.2调试过程中的困难(1)接入5伏电压之后,开关模块中有一个按钮不能起作用,通过万用表检测,发现有一个点没有连接上。(3)软硬件连接时,数码管显示乱码。我们反复检查程序后发现数码管ag的硬件引脚与软件引脚接反了。最后,我们重新连接了引脚,达到了预期的效果。8调试结果说明及分析DN不按下(即发光二极管不亮),说明是白天状态:(1)按下SS,计费数码管显示09,记程数码管开始变化。随着记程数码管显示的数值超过3公里后,计费数码管按超出每公里3元计算。(2)再按下WR,等待时间数码管开始计数,记程、计费数码管均保持不变,当等待时间超过3分钟后,计费数码管按超出每分钟2元计算,记程数码管仍保持不变。(3)再按WR,计费、记程数码管再次发生变化。(4)再按下SS清零。DN按下(即发光二极管发光),说明是黑夜状态:(1)按下SS,计费数码管显示12,记程数码管开始变化。随着记程数码管显示的数值超过3公里后,计费数码管按超出每公里4元计算。(2)再按下WR,等待时间数码管开始计数,记程、计费数码管均保持不变,当等待时间超过3分钟后,计费数码管按超出每分钟1元计算,记程数码管仍保持不变。(3)再按WR,计费、记程数码管再次发生变化。9收获体会经过两个星期的课程设计,我收益颇多。不仅增强了个人的实践能力,也增强了个人与团体的凝聚力,以及学会了在问题中不断探索,不断学习,不断创新的毅力。10.结束语本文介绍了一种全新的出租车计价器计费系统的FPGA设计方法。如果将该设计再结合到实际应用中,那么,只需改变设计中计费要求,就可以应用到出租车上。另外,如果可实现任意输入该出租车计价