资源描述
EDA 课 程 设 计
课 程 ____________
题 目 ____________
学 院 ____________
专业班级
学生姓名
学生学号
指导教师
****年**月**日
题目 出租车自动计费器
摘要
本系统是基于FPGA的模拟出租车计费系统,是在实验室实验箱EP1C6P240C8芯片及其外围电路的基础上完成程序的下载仿真。本系统模拟了出租车计费系统的过程,其中出租车的状态分为等待、行驶,系统能够完成起步价计费,等待、行驶状态计费。
关键字:出租车 计费系统 起步价 等待 行驶
一、 设计目的
1. 掌握出租车计费的工作原理
2. 进一步熟悉用VHDL语言编写出租车计费程序
二、 开发软件: QuartusII
三、 设计任务
1、 设计一个出租车自动计费器,具有行车里程计费、等候时间计费、及起价三部分,用三位数码管显示总金额,最大值为99.9元;
2、 行车里程单价1.7元/公里,等候时间单价1.7元/5分钟,起价8元(3公里起价)。
3、 行车里程的计费电路将汽车行驶的里程数转换成与之成正比的脉冲数,然后由计数译码电路转换成收费金额,实验中以一个脉冲模拟汽车前进十米,则每100个脉冲表示1公里,然后用乘法器将里程数乘以每公里单价的比例系数,从而计算出具体费用。
4、 用数码管显示行驶公里数,三个数码管显示行驶里程。提示:
1、 等候时间计费需将等候时间转换成脉冲个数,用每个脉冲表示的金额与脉冲数相乘即得计费数,脉冲周期为1秒,例如60个脉冲表示1分钟,而5分钟收费1.7元。
2、 用2个LED显示等候时间。
3、 用加法器将几项收费相加,P=P1+P2+P3
4、 P1为起价,P2为行车里程计费,P3为等候时间计费,用四个数码管表示总的计费结果。
四、系统设计原理及过程
1、 基本原理
本次设计首先在QuartusⅡ环境中对出租车自动计费器的各个部分利用VHDL这一硬件描述语言予以设计,生成模块。而整个设计的核心部分就在里程、计时、计费处理模块。里程、计时模块完成行驶距离和等待时间的处理以及起步距离之后和等待时间的计费脉冲的产生。计费处理模块完成起步价计费、在计费脉冲来临之际累加计费的功能。随后运用QuartusⅡ中的仿真功能对其予以仿真,从仿真的结果中分析程序的正确性。待所有模块的功能正确之后,运用原理图搭建电路并进行整体仿真直至达到最初的设计要求,最后再在实验箱上综合下载检验设计的正确与否。
2、 系统框图
根据设计要求,电路具有计时、计程、计费功能,用数码管显示行驶公里数、等待时间、收费金额,行车里程和等待时间的处理电路将汽车行驶的里程数、转换成与之成正比的计费脉冲,然后由计费电路转换成收费金额,实验中以一个脉冲模拟汽车前进十米,则每100个脉冲表示1公里,3公里以后每公里产生一个计费脉冲,一个1HZ的脉冲用来表示等待时间,60个脉冲代表1分钟,5分钟即300个脉冲产生一个等待计费脉冲,然后用计费电路对计费脉冲进行计费。实验箱中只有一个48MHZ的时钟,所以需要分频之后再送给其他模块,最后将等待时间、行驶里程、计费金额经过译码电路送到数码管显示。其设计框图如图1所示:
译码显示
数据选择器
八进制计数器
分频
行驶、等待处理电路
分频
48MHZ时钟
计费电路
图1 整体系统框图
3、 电路及模块分析
系统总体设计电路如图2:
图2 出租车自动计费器顶层电路原理图
1) 行驶里程、等待时间处理模块
本模块是系统的核心模块之一,能够对外部的行驶距离脉冲、等待时间脉冲进行计数。因为行驶距离每脉冲代表10米,所以计满100个数就输出一个行驶距离计费脉冲,因为3公里之内属于起步价,所以前3公里内不输出行驶距离计费脉冲,因为用3位数码管来显示行驶距离,其中两位整数,一位小数,所以行驶距离最小分辨率为0.1公里,行驶距离脉冲每计10个数,行驶距离输出加0.1,行驶距离最大值为99.9公里。等待时间脉冲频率为1HZ,所以一个脉冲代表1秒,60个等待脉冲是1分钟,输出等待时间加1,等待时间5分钟计一次费,所以对等待时间脉冲计数,计满300个数就输出一个等待计费脉冲。等待时间最大值为99分钟。将行驶距离、等待时间送到数据选择器,计费脉冲送到计费模块完成距离、时间的显示以及计费功能。
2) 计费模块
计费模块也是本系统的核心,完成起步价计费,等待时间,行驶计费功能。计费器启动,显示起步价8元,之后每来一个行驶距离计费脉冲或者等待时间计费脉冲,计费金额自动加1.7元。计费显示用3位数码管,所以计费最大值为99.9元。将计费输出送到数据选择器,最后送到译码电路显示。
3) 分频模块
因为实验箱上只有一个48MHZ的时钟,所以我们要经过分频电路得到我们所需要的频率,本系统中用到了三个分频,1HZ分频用来作为等待时间脉冲,10HZ分频作为行驶距离脉冲,每个脉冲代表行驶10米。还有一个分频是作为数码管动态显示的扫频脉冲,由此频率生成一个八进制计数器,作为数据选择器的选择信号,将各个数据位轮流送到数码管,利用人眼的视觉暂留实现动态显示。
4) 八进制计数器模块
八进制计数器模块完成八进制计数,从000计到111后,回到000重新计数,并将此数据送到数据选择器作为选择信号。
5) 八选一数据选择器模块
本模块主要是完成数码管的动态扫描,将八位数据在选择信号的作用下依次送到译码电路,完成动态显示。本模块的主要特点是有一个小数点标志位输出以及段选信号。
6) 译码模块
本模块主要完成数据的译码,在段选信号,小数点标志位的共同作用下完成数据在八位数码管上的动态显示。
五、系统调试及下载
完成个模块的设计之后,将各个模块封装成元件,建立一个原理图文件,将各个模块连接起来,即完成了整个系统的顶层设计,顶层设计框图如上图图2所示。下面对系统的核心模块进行仿真。
1、 里程、等待时间处理模块
里程、行驶距离计费脉冲仿真图
由图可以看出每10个脉冲里程数加0.1,三公里以后每公里有一个计费脉冲B1。
等待时间,等待计费脉冲仿真图
由图可以看出每60个脉冲,等待时间加1。等待时间每5分钟产生一个计费脉冲。
2、 计费模块
计费模块仿真图
由图可以看出在计费脉冲来临之前,计费金额始终是起步价8元,之后每来一个计费脉冲,计费金额加1.7元。
其他模块较简单,这里就不一一仿真了,设计好顶层原理图之后,就可以配置引脚了,在配置引脚之前,先选择芯片EP1C6P240C8,然后配置好START、WR、RST按键,数码管位选、段选引脚就可以下载了。
六、结论
下载完之后,我们可以看到,八位数码管的右三位显示起步价08.0,中间三个数码管在以0.1为步长进行加法显示行驶里程,当行驶里程超过3公里之后,每公里计费金额加1.7元,当我们按下K2键,每分钟左边两个数码管加1,其显示的等待时间,当等待时间到5分钟时,计费金额加1.7元,由此我们可以判断,系统设计符合要求。
实验感想:
附:实验程序
1.1HZ分频
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity pulse is
port(clk: in std_logic;
-- D: in std_logic_vector(7 DOWNTO 0);
Fout: out std_logic);
end;
architecture one of pulse is
signal full:std_logic;
begin
p_reg:process(clk)
variable cnt8: integer range 24000000 downto 0;
begin
if clk'event and clk='1' then
if cnt8=24000000 then
cnt8:=0;
full<='1';
else cnt8:=cnt8+1;
full<='0';
end if;
end if;
end process p_reg;
p_div:process (full)
variable cnt2:std_logic;
begin
if full'event and full='1' then
cnt2:=not cnt2;
If cnt2='1'then fout<='1';
else fout<='0';
end if;
end if;
end process p_div;
end;
2、10HZ分频
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity pulse10 is
port(clk: in std_logic;
-- D: in std_logic_vector(7 DOWNTO 0);
Fout: out std_logic);
end;
architecture one of pulse10 is
signal full:std_logic;
begin
p_reg:process(clk)
variable cnt8: integer range 2400000 downto 0;
begin
if clk'event and clk='1' then
if cnt8=2400000 then
cnt8:=0;
full<='1';
else cnt8:=cnt8+1;
full<='0';
end if;
end if;
end process p_reg;
p_div:process (full)
variable cnt2:std_logic;
begin
if full'event and full='1' then
cnt2:=not cnt2;
If cnt2='1'then fout<='1';
else fout<='0';
end if;
end if;
end process p_div;
end;
3、 扫频分频
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity pulsesp is
port(clk: in std_logic;
-- D: in std_logic_vector(7 DOWNTO 0);
Fout: out std_logic);
end;
architecture one of pulsesp is
signal full:std_logic;
begin
p_reg:process(clk)
variable cnt8: integer range 24000 downto 0;
begin
if clk'event and clk='1' then
if cnt8=24000 then
cnt8:=0;
full<='1';
else cnt8:=cnt8+1;
full<='0';
end if;
end if;
end process p_reg;
p_div:process (full)
variable cnt2:std_logic;
begin
if full'event and full='1' then
cnt2:=not cnt2;
If cnt2='1'then fout<='1';
else fout<='0';
end if;
end if;
end process p_div;
end;
4、 里程、等待时间处理模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY JIFEI IS
PORT(CLK0,CLK1:IN STD_LOGIC;
START:IN STD_LOGIC;
WR:IN STD_LOGIC;
RST:IN STD_LOGIC;
B1,B2:OUT STD_LOGIC;
KM0,KM1,KM2:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
MIN1,MIN0:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END JIFEI;
ARCHITECTURE BEHAVE OF JIFEI IS
BEGIN
RUN:PROCESS(CLK0,START,WR,RST)
VARIABLE R1:INTEGER RANGE 0 TO 9;
VARIABLE R2:INTEGER RANGE 0 TO 99;
VARIABLE K:STD_LOGIC_VECTOR (7 DOWNTO 0);
VARIABLE K2,K1,K0 :STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF RST='0' THEN K0:="0000";K1:="0000";K2:="0000";R1:=0;R2:=0;
ELSIF CLK0'EVENT AND CLK0='1' THEN
IF START='1'AND WR='1' THEN
IF R1=9 THEN R1:=0;
IF K0="1001" THEN
K0:="0000";
IF K1="1001" THEN
K1:="0000";
IF K2="1001" THEN
K2:="0000";
ELSE
K2:=K2+1;
END IF;
ELSE
K1:=K1+1;
END IF;
ELSE
K0:=K0+1;
END IF;
ELSE R1:=R1+1;
END IF;
K:=K2&K1;
IF K>"00000001" THEN
IF R2<99 THEN R2:=R2+1;B1<='0';
ELSE R2:=0;B1<='1';
END IF;
END IF;
END IF;
END IF;
KM0<=K0;KM1<=K1;KM2<=K2;
END PROCESS;
W:PROCESS(CLK1,START,WR,RST)
VARIABLE W1:INTEGER RANGE 0 TO 59;
VARIABLE W2:INTEGER RANGE 0 TO 299;
VARIABLE M1:STD_LOGIC_VECTOR(3 DOWNTO 0);
VARIABLE M0:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF RST='0' THEN M0:="0000";M1:="0000";W1:=0;W2:=0;
ELSIF CLK1'EVENT AND CLK1='1' THEN
IF START='1' AND WR='0'THEN
IF W1=59 THEN W1:=0;
IF M0="1001"THEN
M0:="0000";
IF M1="1001"THEN
M1:="0000";
ELSE M1:=M1+1;
END IF;
ELSE M0:=M0+1;
END IF;
ELSE W1:=W1+1;
END IF;
IF W2<299 THEN W2:=W2+1;B2<='0';
ELSE W2:=0;B2<='1';
END IF;
END IF;
END IF;
MIN0<=M0;
MIN1<=M1;
END PROCESS;
END ARCHITECTURE ;
5、 计费模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY JIN IS
PORT(B:IN STD_LOGIC;
START:IN STD_LOGIC;
RST:IN STD_LOGIC;
P0,P1,P2: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END JIN;
ARCHITECTURE BEHAVE OF JIN IS
BEGIN
P:PROCESS(B,START,RST)
VARIABLE C2,C1,C0:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF RST='0' THEN C0:="0000";C1:="1000";C2:="0000";
ELSIF START='1' THEN
IF B'EVENT AND B='1' THEN
IF C0>2 THEN --加0.7元
IF C1="1001"THEN C1:="0000";
IF C2="1001"THEN C2:="0000";
ELSE C2:=C2+1;
END IF;
ELSE C1:=C1+1;
END IF;
C0:=C0-3;
ELSE C0:=C0+7;
END IF;
IF C1="1001"THEN C1:="0000";
IF C2="1001"THEN C2:="0000";
ELSE C2:=C2+1;
END IF;
ELSE C1:=C1+1;
END IF;
END IF;
END IF;
P0<=C0;P1<=C1;P2<=C2;
END PROCESS;
END;
6、 八进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT8 IS
PORT (CLK : IN STD_LOGIC;
OUTY : OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END CNT8;
ARCHITECTURE behav OF CNT8 IS
BEGIN
PROCESS(CLK)
VARIABLE CQI : STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
IF CLK'EVENT AND CLK='1' THEN
IF CQI < "111" THEN CQI := CQI + 1;
ELSE CQI := "000";
END IF;
END IF;
OUTY <= CQI;
END PROCESS;
END behav;
7、 八选一数据选择器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MAX81 IS
PORT (P0,P1,P2,K0,K1,K2,M0,M1: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
D : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
POINT:OUT STD_LOGIC);
END MAX81;
ARCHITECTURE body_mAx81 OF mAx81 IS
BEGIN
process (P0,P1,P2,K0,K1,K2,M0,M1,S)
begin
case S is
WHEN "000"=>D<= P0;B<="11111110";POINT<='0';
WHEN "001"=>D<= P1;B<="11111101";POINT<='1';
WHEN "010"=>D<= P2;B<="11111011";POINT<='0';
WHEN "011"=>D<= K0;B<="11110111";POINT<='0';
WHEN "100"=>D<= K1;B<="11101111";POINT<='1';
WHEN "101"=>D<= K2;B<="11011111";POINT<='0';
WHEN "110"=>D<= M0;B<="10111111";POINT<='0';
WHEN "111"=>D<= M1;B<="01111111";POINT<='0';
WHEN others => null;
end case;
end process;
END body_MAX81;
8、 数码管译码程序
Library ieee;
use ieee.std_logic_1164.all;
entity decl7s is
port(a:in std_logic_vector(3 downto 0);
POINT:IN STD_LOGIC;
led7s:out std_logic_vector(7 downto 0));
end decl7s;
architecture one of decl7s is
begin
process(a,POINT)
begin
IF POINT='0' THEN
case a is
when "0000"=>led7s<="11000000";
when "0001"=>led7s<="11111001";
when "0010"=>led7s<="10100100";
when "0011"=>led7s<="10110000";
when "0100"=>led7s<="10011001";
when "0101"=>led7s<="10010010";
when "0110"=>led7s<="10000010";
when "0111"=>led7s<="11111000";
when "1000"=>led7s<="10000000";
when "1001"=>led7s<="10010000";
when others=>null;
end case;
ELSE
case a is
when "0000"=>led7s<="01000000";
when "0001"=>led7s<="01111001";
when "0010"=>led7s<="00100100";
when "0011"=>led7s<="00110000";
when "0100"=>led7s<="00011001";
when "0101"=>led7s<="00010010";
when "0110"=>led7s<="00000010";
when "0111"=>led7s<="01111000";
when "1000"=>led7s<="00000000";
when "1001"=>led7s<="00010000";
when others=>null;
end case;
END IF;
end process;
end;
展开阅读全文