数电实验报告VHDL电梯控制器.docx
《数电实验报告VHDL电梯控制器.docx》由会员分享,可在线阅读,更多相关《数电实验报告VHDL电梯控制器.docx(18页珍藏版)》请在冰豆网上搜索。
数电实验报告VHDL电梯控制器
数字电路与逻辑设计
实验报告
班级:
2010211111班
姓名:
***
班内序号:
01号
学号:
*******1
北京邮电大学
BeijingUniversityofPostsandTelecommunications
简易三层电梯控制器
一、设计课题的任务要求
1.基本要求:
i)电梯设有一层、二层外部呼叫按钮和内部一层、二层指定按钮(BTN);
ii)利用数码管显示电梯所在楼层,用LED显示电梯运行状态如上行、下行、开门、关门等。
2.提高要求:
i)点阵显示楼层;
ii)用点阵显示楼层的上下滚动移出移入表示电梯的上行或下行运行方向;
iii)增加为三层电梯控制器。
二、系统设计(包括设计思路、总体框图、分块设计)
1.设计思路:
这个电梯控制器的核心是数字电路的状态转移思想。
我将三层电梯的状态划分为一层(S0),二层上(S1),二层下(S2),三层(S3)四种,根据不同的输入进行状态转移,实现电梯的上下运行这一功能。
而对于开关门状态,则放在对楼层(position)和按键(inside,outside)识别之后,状态转移之前,这样大幅减少了程序所需的状态数量,提高了代码的效率。
下面我将根据程序的输入、输出和运行对程序的设计思路做一个简要的介绍:
i)输入:
程序的输入端口有时钟(clk)、复位(reset)、内部按键(inside)和外部按键(outside)。
时钟(clk)提供系统所需的时钟频率,是程序正常运行,复位(reset)能够使程序在异常状态下初始化,主要是为了方便在硬件上调试而设置的;
内部按键(inside)为3位逻辑向量,对应实际电梯内部的按键1、2、3层按钮;
外部按键(outside)为4位逻辑向量,对应实际电梯外部1层上、2层上、2层下和3层下按钮。
ii)输出:
程序输出端口有方向(direction)、内部按键灯(inlight)、外部按键灯(outlight)、楼层显示数码管(legout)和状态显示点阵(rowo、colo)。
方向(direction)这个输出端口是起初没有实现点阵时使用的,最后完成时,可以采用单独的led显示,也可整合在状态显示点阵(rowo、colo)的功能中;
内部按键灯(inlight)和外部按键灯(outlight)是对输入端内部按键(inside)和外部按键(outside)的实时显示端口,表示现在又那些按钮被按下;
楼层显示数码管(legout)用来显示当前楼层;
状态显示点阵(rowo、colo)用来显示停留时开、关门状态,以及电梯的上升下降状态。
iii)运行过程:
电梯状态判断的进程:
a.接通电源后,电梯进行初始化,将有关信号置0;
b.然后对输入端口进行读取,将按键(inside、outside)赋给对应信号(inside_var、outside_var);
c.根据当前状态信号(current_state)判断当前位置,再根据按键信号(inside_var、outside_var)与楼层信号(position)的关系判断进一步操作;
例如:
电梯处于2层上状态时,先后进行如下判断,若不成立进行下一判断——若内部2层按键或外部2层上按键被按下,则停留开门然后关门;若内外部3层按键被按下,那么确定下一个状态(next_state)为3层;若内外部1层按键或外部2层下按键被按下,那么确定下一个状态(next_state)为2层下;若所有按键均不被按下,则停留不开门,即确定下一个状态(next_state)为2层上。
循环c。
状态转换(即电梯上下行)的进程:
每隔一段时间将下一个状态(next_state)赋给当前状态(current_state)。
显示进程:
将程序中的信号赋给对应的输出端口,实现电梯位置、电梯运行状态、按键状态等的实时输出。
2.总体框图:
3.
分块设计:
三、仿真波形及波形分析
输入按键,对应的按键灯亮
示例:
电梯在一层时,输入电梯内部三层按键(inside
(2)<=1),按键灯亮(inlight
(2)<=0),方向变为向上(direction<=1),电梯一次从一层上升到二层(position<=2),再从二层上升到三层(position<=3),门开(door<=1),延迟(状态保持不变),门关(door<=0),电梯三层内部按键灯灭(inlight
(2)<=0),之后无输入,故保持在三层关门状态。
四、源程序(要有注释)
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.all;
USEIEEE.STD_LOGIC_ARITH.all;
USEIEEE.STD_LOGIC_UNSIGNED.all;
ENTITYelevatorIS
PORT(
clk:
INSTD_LOGIC;
reset:
INSTD_LOGIC;
outside:
INSTD_LOGIC_VECTOR(3DOWNTO0);--outside为电梯外部按钮,0为一层,1为二层上升,2为二楼下降,3为三层下降
inside:
INSTD_LOGIC_VECTOR(2DOWNTO0);--inside为电梯内部按钮,0为一层,1为二层,2为三层
direction:
INOUTSTD_LOGIC;--direction为电梯运行方向,'1'为上楼,'0'为下楼
outlight:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);--外部按键亮灯
inlight:
OUTSTD_LOGIC_VECTOR(2DOWNTO0);--内部按键亮灯
ledag:
OUTSTD_LOGIC_VECTOR(7downto0);--定义数码管的七段输出信号
rowo:
OUTSTD_LOGIC_VECTOR(7DOWNTO0);--点阵行
colo:
OUTSTD_LOGIC_VECTOR(7DOWNTO0)--点阵列
);
ENDelevator;
ARCHITECTUREarchOFelevatorIS
TYPEstateIS(S0,S1,S2,S3);--S0一层,S1二楼上,S2二楼下S3三层;
SIGNALcurrent_state:
state;--当前状态信号
SIGNALnext_state:
state;--下一状态信号
SIGNALup:
STD_LOGIC;--方向信号
SIGNALcurrent_out:
STD_LOGIC_VECTOR(3DOWNTO0);--4位外部按键信号,与输入端outside对应
SIGNALcurrent_in:
STD_LOGIC_VECTOR(2DOWNTO0);--3位内部按键信号,与inside对应
SIGNALtmp:
INTEGERRANGE0TO99999;--用于分频器
SIGNALclk_out:
STD_LOGIC;--分频器输出
SIGNALposition:
INTEGERRANGE0TO2;--位置信号
SIGNALrow:
STD_LOGIC_VECTOR(7DOWNTO0);--点阵行
SIGNALcol:
STD_LOGIC_VECTOR(7DOWNTO0);--点阵列
signaldottemp:
integerrange0to7;--用于使8行点阵交替输出
SIGNALdoor:
STD_LOGIC;--开门信号
SIGNALchange:
STD_LOGIC;--电梯运动信号
BEGIN
P1:
PROCESS(clk)--分频器
BEGIN
IFclk'eventANDclk='1'THEN
IFtmp>4999THEN
tmp<=0;
ELSE
tmp<=tmp+1;
ENDIF;
ENDIF;
ENDPROCESS;
P2:
PROCESS(tmp)--分频器
BEGIN
IFtmp=4999THEN
clk_out<='1';
ELSE
clk_out<='0';
ENDIF;
ENDPROCESS;
P3:
PROCESS(clk_out)--电梯移动进程
VARIABLEdelay:
INTEGERRANGE0TO9999;
BEGIN
IFclk_out'EVENTANDclk_out='1'THEN--检测时钟上升沿
IFdelay<9999THEN--延迟,代表电梯移动
delay:
=delay+1;
ELSE
delay:
=0;
current_state<=next_state;--下一状态赋给当前状态,即到达
ENDIF;
ENDIF;
ENDPROCESS;
P4:
PROCESS(reset,clk_out,current_state,up,outside,inside)
VARIABLEoutside_var:
STD_LOGIC_VECTOR(3DOWNTO0);--外部按键对应变量
VARIABLEinside_var:
STD_LOGIC_VECTOR(2DOWNTO0);--内部按键对应变量
VARIABLEdelay:
INTEGERRANGE0TO9999;
BEGIN
IFreset='1'THEN--复位,初始化
next_state<=S0;
position<=0;
delay:
=0;
up<='0';
door<='0';
outside_var(3DOWNTO0):
="0000";
inside_var(2DOWNTO0):
="000";
ELSIFclk_out'eventandclk_out='1'THEN--若无复位信号,用输入给变量赋值
IFoutside(0)='1'THENoutside_var(0):
='1';ENDIF;--外部按键
IFoutside
(1)='1'THENoutside_var
(1):
='1';ENDIF;
IFoutside
(2)='1'THENoutside_var
(2):
='1';ENDIF;
IFoutside(3)='1'THENoutside_var(3):
='1';ENDIF;
IFinside(0)='1'THENinside_var(0):
='1';ENDIF;--内部按键赋值
IFinside
(1)='1'THENinside_var
(1):
='1';ENDIF;
IFinside
(2)='1'THENinside_var
(2):
='1';ENDIF;
CASEcurrent_stateIS
WHENS0=>--当电梯位于一楼时
position<=0;--对楼层信息更新
IF(outside_var(0)orinside_var(0))='1'THEN–若内外有一层按键按下
door<='1';--开门
change<='0';--停止
IFdelay<9900THEN
delay:
=delay+1;
ELSE
door<='0';--关门
delay:
=0;
outside_var(0):
='0';--清除内外按键变量
inside_var(0):
='0';
ENDIF;
ELSIF(outside_var
(1)ORoutside_var
(2)oroutside_var(3)orinside_var
(2)orinside_var
(1))='1'THEN--一层无按键按下,同方向有
next_state<=S1;--下一状态设为二层
delay:
=0;
up<='1';
change<='1';
ELSE
next_state<=S0;
delay:
=0;
change<='0';
ENDIF;
WHENS1=>--二楼上状态处理
position<=1;--对楼层信息更新
IF(inside_var
(1)oroutside_var
(1))='1'THEN--如果内部二或外部二上被按下
door<='1';--开门
change<='0';
IFdelay<9900THEN
delay:
=delay+1;
ELSE
door<='0';--关门
delay:
=0;
inside_var
(1):
='0';--清除内部按键
outside_var
(1):
='0';--外部二上清除
ENDIF;
ELSIF(outside_var
(1)oroutside_var(3)orinside_var
(2))='1'THEN--如果同方向有按键被按下
next_state<=S3;--目的层为三层
change<='1';
ELSIF(outside_var(0)oroutside_var
(2)orinside_var(0))='1'THEN--如果反方向有按键被按下
next_state<=S2;--目标层是二下
up<='0';
change<='1';
ELSE
next_state<=S1;
change<='0';
ENDIF;
WHENS2=>--二层下状态
position<=1;
IF(inside_var
(1)oroutside_var
(2))='1'THEN--有同层被按下
door<='1';--开门
change<='0';
IFdelay<9900THEN
delay:
=delay+1;
ELSE
door<='0';--关门
delay:
=0;
inside_var
(1):
='0';
outside_var
(2):
='0';
ENDIF;
ELSIF(outside_var(0)orinside_var(0))='1'THEN--无同层,但有同方向
next_state<=S0;--目的层为一层
change<='1';
ELSIF(outside_var
(1)oroutside_var(3)orinside_var
(2))='1'THEN--无同层,无同方向,有反方向
next_state<=S1;--目的层为二层上
up<='1';
change<='1';
ELSE
next_state<=S2;--目的层为二层下
change<='0';
ENDIF;
WHENS3=>--电梯三楼状态处理
position<=2;
IF(outside_var(3)orinside_var
(2))='1'THEN--有同层
door<='1';--开门
change<='0';
IFdelay<9900THEN
delay:
=delay+1;
ELSE
door<='0';--关门
delay:
=0;
outside_var(3):
='0';--按键清除
inside_var
(2):
='0';
ENDIF;
ELSIF(inside_var(0)orinside_var
(1)oroutside_var(0)oroutside_var
(1)oroutside_var
(2))='1'THEN--有低层被按下
next_state<=S2;--目的层为二层向下
up<='0';
change<='1';
ELSE
next_state<=S3;--目的层为三层
change<='0';
ENDIF;
ENDCASE;
ENDIF;
current_out<=outside_var;--更新内外部按键
current_in<=inside_var;
ENDPROCESS;
P5:
PROCESS(up,position)--电梯上下,开关门显示
CONSTANTd0:
STD_LOGIC_VECTOR(7DOWNTO0):
="11111111";
CONSTANTd1:
STD_LOGIC_VECTOR(7DOWNTO0):
="10000001";
CONSTANTd2:
STD_LOGIC_VECTOR(7DOWNTO0):
="00011000";
CONSTANTd3:
STD_LOGIC_VECTOR(7DOWNTO0):
="00000011";
CONSTANTd4:
STD_LOGIC_VECTOR(7DOWNTO0):
="11000000";
BEGIN
direction<=up;--更新方向、按键亮灯输出端口
outlight<=current_out;
inlight<=current_in;
ifclk_out='1'then
casepositionis--根据楼层调整数码管显示
when0=>ledag<="00000110";
when1=>ledag<="01011011";
when2=>ledag<="01001111";
whenothers=>null;
endcase;
ifdottemp=7then
dottemp<=0;
elsedottemp<=dottemp+1;
endif;
IFchange='0'THEN--根据运行、开门信号显示开关门或上下行状态
ifdoor='1'then
casedottempis
when0=>row<="01111111";col<="10000001";
when1=>row<="10111111";col<="10000001";
when2=>row<="11011111";col<="10000001";
when3=>row<="11101111";col<="10000001";
when4=>row<="11110111";col<="10000001";
when5=>row<="11111011";col<="10000001";
when6=>row<="11111101";col<="10000001";
when7=>row<="11111110";col<="10000001";
whenothers=>null;
endcase;
elsifdoor='0'then
casedottempis
when0=>row<="01111111";col<="11111111";
when1=>row<="10111111";col<="11111111";
when2=>row<="11011111";col<="11111111";
when3=>row<="11101111";col<="11111111";
when4=>row<="11110111";col<="11111111";
when5=>row<="11111011";col<="11111111";
when6=>row<="11111101";col<="11111111";
when7=>row<="11111110";col<="11111111";
whenothers=>null;
endcase;
endif;
ELSE
IFup='1'THEN
casedottempis
when0=>row<="01111111";col<="00011000";
when1=>row<="10111111";col<="00111100";
when2=>row<="11011111";col<="01011010";
when3=>row<="11101111";col<="10011001";
when4=>row<="11110111";col<="00011000";
when5=>row<="11111011";col<="00011000";
when6=>row<="11111101";col<="00011000";
when7=>row<="11111110";col<="00011000";
ENDCASE;
ELSE
casedottempis
when0=>row<="01111111";col<="00011000";
when1=>row<="10111111";col<="00011000";
when2=>row<="11011111";col<="00011000";
when3=>row<="11101111";col<="00011000";
when4=>row<="11110111";col<="10011001";
when5=>row<="11111011";col<="01011010";
when6=>row<="11111101";col<="00111100";
when7=>row<="11111110";col<="00011000";
endcase;
ENDIF;
ENDIF;
endIF;
rowo<=row;--将点阵信号输出到点阵输出端口
colo<=col;
ENDPROCESS;
ENDarch;
五、功能说明
本程序实现了一般三层电梯的功能,初始状态为处于一层停止关门状态。
输入端分为电梯内部按键1,2,3层,以及外部按键1层,2层向上,2层向下,电梯会根据当前位置以及按键按下的情况进行开关门、上下行的等操作。
输出端有点阵、数码管和LED组成,点阵显示开关门、上下行状态,数码管显示楼层,LED显示按键按下状况。
以下是电梯处于一二三层时,对于不同输入情况的输出的列举:
当电梯处于一层:
若门内一层按键或门外一层按键被按下时,电梯仍处于一层,门被打开,延迟一段时间后关门,否则:
若一层以上按键被按下时,电梯从一层上升,经过一段时间到达二层,否则:
若没有按键被按下,那么电梯维持在一层关门状态不变。
当电梯处于二层向上状态:
此时判断二层的内部按键及二层的外部向上按键是否被按下,若是则电梯停止,开门,延迟,关门,否则:
若三层内或外按键被按下,那么电梯向上升,经过一段时间到达三层,否则:
若二层外向