北邮电子 数电综合实验报告.docx
《北邮电子 数电综合实验报告.docx》由会员分享,可在线阅读,更多相关《北邮电子 数电综合实验报告.docx(27页珍藏版)》请在冰豆网上搜索。
北邮电子数电综合实验报告
数字电路综合实验设计
简易出租车计价器的设计与实现
学院:
电子工程学院
班级:
2011211203
学号:
2011210876
姓名:
孙月鹏
班内序号:
04
摘要
本文介绍了利用QuartusII综合性PLD/FPGA开发软件,在MAXII数字逻辑实验开发板上实现简易出租车计价器功能的设计与实现方法。
本方案采用自上而下的设计理念,将整体电路按照功能划分为分频、计数、控制、数码管显示电路、点阵显示电路等若干模块,模块内用VHDL语言完成逻辑设计,模块间用原理图进行连接,使整体可实现计费、计时等功能。
关键字:
可编程器件模块化设计出租车计价器VHDL语言
一、设计任务要求
Ø设计一台出租车计价器,不同情况下具有不同的收费标准。
基本要求:
1.行驶公里:
用时钟2秒钟表示出租车匀速行驶1公里。
在行车5公里以内,按起步价13元收费,超过5公里部分,以每公里2元收费。
燃油附加费每运次1元。
2.途中等待:
用按键控制中途等待,等待少于(包括)5秒不收费,超过5秒后没等待3秒钟加收1元。
3.用数码管分时显示计费金额、行驶里程和等候时间。
字母A表示当前处于显示计费金额状态,字母B表示当前处于显示行驶里程状态,字母C表示当前处于显示等候时间状态。
4.用按键控制出租车空驶、载客状态。
提高要求:
1.用点阵滚动显示收费单据。
2.具有夜间模式,基本单价加收20%的费用。
出租车收费以元为单位,元以下四舍五入。
3.出租车行驶速度可调可控。
4.多人乘车,分段计价。
5.自拟其他功能。
2、设计思路与结构框图
1.设计思路
图1结构框图
由结构框图可以分析得出,该系统的的主体是计数控制器。
该系统由外部控制载客控制信号和等待控制信号,以时钟信号的翻转为计数依据,完成对时间、里程和费用的计数,并将结果通过数码管译码电路显示出来。
该系统的控制信号可由拨码或按键输入,时钟由开发板内部时钟分频得出,输出有点阵输出和数码管输出。
因此,可将系统分为分频器、计数控制器、数码管译码和显示以及点阵显示四部分。
并以此得出系统的逻辑框图如下:
图2逻辑框图
2.
控制器部分的状态转移图
Ø该控制器一共有三个基本状态:
空驶状态、载客状态和等待状态。
Ø分别由v、和w来进行控制。
3、
图3状态转移图
分块电路和总体电路设计
(1)
图4总体电路设计
总体电路设计
Ø整体电路由数码管译码电路、转换电路、点阵译码电路、技术控制电路、分频电路五部分构成。
Ø分频电路将开发板内部的50MHz时钟分为500hz(供给数码管和点阵)、1Hz(控制器计时)、0.5Hz(行驶路程计费)、0.3Hz(等待时间计费)以及用于提高分频效率的其他若按频率。
Ø计数控制电路由四部分构成,整体完成行驶距离的计数、等待时间的计数以及费用的计数。
输出为三组十位二进制数。
Ø转换电路有转换数据类型和在数码管上分时显示两个功能。
首先将输入的十位二进制数转换为4位十进制数,并且利用除法和取余数的运算提取出个位、十位、百位、千位,并转换为四位二进制BCD码。
其次利用0.5hz的时钟,将行驶里程、等待时间、计费金额以2秒为周期依次out1~4,供给数码管以便分时显示。
Ø数码管译码电路以500HZ实现动态扫描,并将转换电路输出的5组BCD码依次译码,完成显示。
Ø点阵译码器根据载客控制信号,分别显示“O”、“X”静态图案。
(2)分块电路设计
1.
分频器(以100分频为例)
1.1电路模块
1.2关键代码
ENTITYdiv_100IS
PORT(
clk100:
INSTD_LOGIC;--输入时钟
clear:
INSTD_LOGIC;
clk1:
OUTSTD_LOGIC);--输出时钟
ENDdiv_100;
ARCHITECTUREa100OFdiv_100IS
SIGNALtmp100:
INTEGERRANGE0TO99;--计数信号
BEGIN
p1:
PROCESS(clear,clk100)--p1进行100进制的计数
BEGIN
IFclear='0'THEN
tmp100<=0;
ELSIFclk100'eventANDclk100='1'THEN
IFtmp100=99THEN
tmp100<=0;
ELSE
tmp100<=tmp100+1;
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk100)--p2输出占空比为50%的新时钟
BEGIN
IFclk100'eventANDclk100='1'THEN
IFtmp100>49THEN
clk1<='1';
ELSE
clk1<='0';
ENDIF;
ENDIF;
ENDPROCESSp2;
ENDa100;
1.3仿真波形
图5200分频仿真波形
2.计数控制器
2.1电路模块
图7电路控制器
计数控制器由四部分组成,输入为三个不同频率的时钟、载客控制信号v和等待控制信号w。
control1完成里程的计数cd和行驶费用cm1,control2完成等待时间ct的计数和等待开始计费(ct>5s)信号outt,control3接收到outt后输出为等待时间的计费cm2,control4为总费用(cm1+cm2+燃油附加费1元)。
设计关键思想是将费用、行驶里程、等待时间三个计数过程分开处理,并且将行驶计费和等待计费也分开处理。
通过载客信号v、等待信号w分别触发不用的进程完成计数。
因为行驶过程中每两秒1公里,每公里两元,等待过程中每三秒1元,因此分别用1hz、0.5hz、0.33hz的时钟完成计时、计费、记里程。
2.2模块control1
2.2.1电路模块
Ø行驶里程计数cd和行驶计费cm1
2.2.2关键代码
ENTITYcontrol1IS
PORT(
clk2:
INSTD_LOGIC;--输入是0.5Hz的时钟
v:
INSTD_LOGIC;--载客控制输入信号
w:
INSTD_LOGIC;--等待信号
cm1:
OUTSTD_LOGIC_VECTOR(9DOWNTO0);--里程计费
cd:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));--行驶距离
ENDcontrol1;
ARCHITECTUREcOFcontrol1IS
SIGNALtemp1:
STD_LOGIC_VECTOR(9DOWNTO0);
SIGNALtemp_cm:
STD_LOGIC;
BEGIN
p1:
PROCESS(clk2,v,w)--p1里程计数
BEGIN
IF(clk2'eventandclk2='1')THEN
IFv='0'THEN--v=0时重新计数
temp1<="0000000000";
ELSIFw='1'THEN--开始等待时里程保持不变
temp1<=temp1;
ELSEtemp1<=temp1+1;
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk2,temp1)
BEGIN
IF(clk2'eventandclk2='1')THEN
IFtemp1<"0000000110"THEN--小于5公里起步价13元
cm1<="0000001101";
cd<=temp1;
ELSEcm1<=temp1+temp1+"0000000011";--大于5公里时的费用
cd<=temp1;
ENDIF;
ENDIF;
ENDPROCESSp2;
ENDc;
2.3模块control2
2.3.1电路模块
Ø等待时间计数ct和等待开始计费信号outt(ct>5s)
2.3.2关键代码
ENTITYcontrol2IS
PORT(
clk1:
INSTD_LOGIC;--输入是1Hz的时钟
v:
INSTD_LOGIC;--载客控制输入信号
w:
INSTD_LOGIC;--等待信号
outt:
outSTD_LOGIC;--若大于5秒,输出1
ct:
outSTD_LOGIC_VECTOR(9DOWNTO0));--等待时间输出
ENDcontrol2;
ARCHITECTUREcOFcontrol2IS
SIGNALtempt:
STD_LOGIC_VECTOR(9DOWNTO0);
SIGNALtemp1:
INTEGERRANGE0TO999;
BEGIN
p3:
PROCESS(clk1,v,w)--累加等待时间
BEGIN
IF(clk1'eventandclk1='1')THEN
IFv='0'THEN
tempt<="0000000000";--v=0清零重置
temp1<=0;
outt<='0';
ELSIFw='0'THEN--行驶时保持状态
tempt<=tempt;
temp1<=temp1;
ELSEtempt<=tempt+1;--等待时技术开始
temp1<=temp1+1;
IFtemp1>4THEN--大于5秒时outt=1
outt<='1';
ELSEoutt<='0';
ENDIF;
ENDIF;
ENDIF;
ENDPROCESSp3;
p4:
PROCESS(clk1,tempt)--将信号赋给输出ct
BEGIN
ct<=tempt;
ENDPROCESSp4;
ENDc;
2.4模块control3
2.4.1电路模块
Ø当输入outt为1时,开始计数
Øcm2为等待时间计费
2.4.2关键代码
ENTITYcontrol3IS
PORT(
clk3:
INSTD_LOGIC;--输入是0.3Hz的时钟
outt:
INSTD_LOGIC;--为1时,等待时间大于5s
v:
INSTD_LOGIC;--载客控制输入信号
w:
INSTD_LOGIC;--等待信号
cm2:
outSTD_LOGIC_VECTOR(9DOWNTO0));--等待计费
ENDcontrol3;
ARCHITECTUREcOFcontrol3IS
SIGNALtempm:
STD_LOGIC_VECTOR(9DOWNTO0);
BEGIN
p5:
PROCESS(clk3,outt,v,w)
BEGIN
IFoutt='1'THEN--大于5秒时开始计费
IF(clk3'eventandclk3='1')THEN
IFv='0'THEN
tempm<="0000000000";--乘客下车等待时间重置
ELSIFw='0'THEN--行驶时保持状态
tempm<=tempm;
ELSEtempm<=tempm+1;--等待时开始计费
ENDIF;
ENDIF;
ENDIF;
ENDPROCESSp5;
p6:
PROCESS(clk3,tempm)
BEGIN
IFV='0'THEN
cm2<="0000000000";
ELSE
cm2<=tempm;--将信号赋给输出:
等待计费cm2
ENDIF;
ENDPROCESSp6;
ENDc;
2.5control4
2.5.1电路模块
Ø将等待计费cm2和行驶计费cm1相加,并加上燃油费1元,得到总费用cm
2.5.2关键代码
ENTITYcontrol4IS
PORT(
clk2:
INSTD_LOGIC;--输入是0.5Hz的时钟
v:
INSTD_LOGIC;--载客控制输入信号
cm1:
inSTD_LOGIC_VECTOR(9DOWNTO0);--行驶费用
cm2:
inSTD_LOGIC_VECTOR(9DOWNTO0);--等待费用
cm:
outSTD_LOGIC_VECTOR(9DOWNTO0));--总费用
ENDcontrol4;
ARCHITECTUREcOFcontrol4IS
BEGIN
p5:
PROCESS(clk2,v)
BEGIN
IF(clk2'eventandclk2='1')THEN
IFv='0'THEN
cm<="0000000000";
ELSEcm<=cm1+cm2+1;
ENDIF;
ENDIF;
ENDPROCESSp5;
ENDc;
2.6控制计数部分的总仿真波形
3.转换器
3.1电路模块
Ø由三个输入:
行驶距离cd、等待时间ct、计费金额cm
Ø输出out1-5为四位二进制BCD码
Ø实现功能:
将十位二进制数按照位数转为为BCD码
3.2关键代码
ENTITYtransformIS
PORT(
clk:
INSTD_LOGIC;--0.5hz的时钟
v:
INSTD_LOGIC;
cd:
inSTD_LOGIC_VECTOR(9DOWNTO0);--行驶距离
ct:
inSTD_LOGIC_VECTOR(9DOWNTO0);--等待时间
cm:
inSTD_LOGIC_VECTOR(9DOWNTO0);--总费用
out1:
outstd_logic_vector(3downto0);--输出个位
out2:
outstd_logic_vector(3downto0);--输出十位
out3:
outstd_logic_vector(3downto0);--输出百位
out4:
outstd_logic_vector(3downto0);--输出千位
out5:
outstd_logic_vector(3downto0));--输出ABC
ENDtransform;
ARCHITECTUREcOFtransformIS
signalcc:
integerrange0to1023;
signalt:
std_logic_vector(1downto0);
signalq1,q2,q3:
integerrange0to1000;
BEGIN
p1:
PROCESS(clk,v)--p1进行3进制的计数
BEGIN
IF(clk'eventandclk='1')THEN
IFv='0'THEN
t<="00";
elsift="00"then
t<="01";
elsift="01"then
t<="10";
elsift="10"then
t<="00";
elset<="00";
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
process(clk,t)
BEGIN
if(clk'eventandclk='1')then
CASEtis--实现分时显示
when"00"=>cc<=CONV_INTEGER(cm);out5<="1010";--计费,显示A
when"01"=>cc<=CONV_INTEGER(cd);out5<="1011";--计里程,显示b
when"10"=>cc<=CONV_INTEGER(ct);out5<="1100";--计时,显示c
whenothers=>cc<=cc;--将十位2进制转为十进制
ENDCASE;
q1<=cc/10;--除法结果为整数部分
q2<=q1/10;
q3<=q2/10;
out1<=conv_std_logic_vector(ccrem10,4);--取得个位
out2<=conv_std_logic_vector(q1rem10,4);--取得十位
out3<=conv_std_logic_vector(q2rem10,4);--取得百位
out4<=conv_std_logic_vector(q3rem10,4);--取得千位
endif;
endprocessp2;
ENDc;
4.数码管译码电路
4.1电路模块
4.2关键代码
ENTITYshumaguanIS
PORT(
clk1:
INSTD_LOGIC;---500hz数码管扫描时钟
out5,out4,out3,out2,out1:
INSTD_LOGIC_VECTOR(3DOWNTO0);
g:
OUTSTD_LOGIC_VECTOR(6DOWNTO0);
cat:
OUTSTD_LOGIC_VECTOR(5DOWNTO0));
ENDshumaguan;
ARCHITECTUREaOFshumaguanIS
SIGNALtmpg:
STD_LOGIC_VECTOR(6DOWNTO0);
SIGNALtmpn:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALtmpc:
INTEGERRANGE0TO5;
BEGIN
p1:
PROCESS(clk1)--六进制计数
BEGIN
if(clk1'eventandclk1='1')then
iftmpc=5then
tmpc<=0;
else
tmpc<=tmpc+1;
ENDIF;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk1)--数码管选通轮流显示
BEGIN
if(clk1'eventandclk1='1')then--将个位、十位等赋给各个数码管
casetmpcis
WHEN0=>tmpn<=out1;cat<="111110";
WHEN1=>tmpn<=out2;cat<="111101";
WHEN2=>tmpn<=out3;cat<="111011";
WHEN3=>tmpn<=out4;cat<="110111";
WHEN5=>tmpn<=out5;cat<="011111";--显示abc
WHENOTHERS=>tmpn<="1101";cat<="000000";
ENDCASE;
ENDIF;
ENDPROCESSp2;
p3:
PROCESS(tmpn)--译码电路
BEGIN
CASEtmpnIS
WHEN"0000"=>tmpg<="1111110";--0
WHEN"0001"=>tmpg<="0110000";--1
WHEN"0010"=>tmpg<="1101101";--2
WHEN"0011"=>tmpg<="1111001";--3
WHEN"0100"=>tmpg<="0110011";--4
WHEN"0101"=>tmpg<="1011011";--5
WHEN"0110"=>tmpg<="1011111";--6
WHEN"0111"=>tmpg<="1110000";--7
WHEN"1000"=>tmpg<="1111111";--8
WHEN"1001"=>tmpg<="1111011";--9
WHEN"1010"=>tmpg<="1110111";--A
WHEN"1011"=>tmpg<="0011111";--B
WHEN"1100"=>tmpg<="1001110";--C
WHEN"1101"=>tmpg<="0000000";--blank
WHENOTHERS=>tmpg<="ZZZZZZZ";
ENDCASE;
ENDPROCESSp3;
g<=tmpg;
ENDa;
5.
点阵译码电路
5.1电路模块
5.2关键代码
ENTITYdzis
PORT(
clk500:
INSTD_LOGIC;
v:
INSTD_LOGIC;
row:
OUTSTD_LOGIC_VECTOR(7DOWNTO0);--行
col:
OUTSTD_LOGIC_VECTOR(7DOWNTO0));--列ENDdz;
ARCHITECTUREaOFdzIS
SIGNALtmp_row:
STD_LOGIC_VECTOR(7DOWNTO0);
SIGNALtmp_col:
STD_LOGIC_VECTOR(7DOWNTO0);
begin
process(v,clk500)
begin
if(clk500'eventandclk500='1')then
ifv='0'then
casetmp_colis
WHEN"11111110"=>tmp_col<="01111111";tmp_row<="00111100";
WHEN"01111111"=>tmp_col<="10111111";tmp_row<="01000010";
WHEN"10111111"=>tmp_col<="11011111";tmp_row<="10000001";WHEN"11011111"=>tmp_col<="11101111";tmp_row<="10000001";
WHEN"11101111"=>tmp_col<="11110111";tmp_row<="10000001";
WHEN"11110111"=>tmp_col<="11111011";tmp_row<="10000001";WHEN"11111011"=>tmp_col<="11111101";tmp_row<="01000010";WHEN"11111101"=>tmp_col<="11111110";tmp_row<="00111100";
WHENOTHERS=>tmp_col<="01111111";tmp_row<="00000