电梯控制系统的设计与实现
电梯控制系统(汇编实现)
电梯控制系统的设计与实现
1.设计目的
- 掌握8086CPU、电路板、可编程接口芯片以及8086汇编语言的应用
- 能够构建一个较完整的微型计算机控制系统
- 具备微机系统的设计能力、电子产品的制作能力和汇编语言的编程能力
2.设计内容
电梯控制系统:初始状态显示在一楼,乘客按下“+”号,表示电梯要上升,(按下“-”号,表示电梯要下降),按下1~6作为目的楼层,并显示在数码管上,电梯上升(下降)过程中,代表相应楼层的发光二极管顺序点亮直至到达目的楼层。
3.设计过程
1)实验步骤
① 根据实验内容设计实验方案,确定电梯运行逻辑,并选择接口芯片与外设;
② 根据方案设计编写汇编代码实现电梯运行;
③ 试验箱连线并将代码加载到试验箱内存中,调试运行代码,确定电梯运行正常;
④ 确定电路板布线并焊接,画出电路板布线图并按照布线图焊接电路板,将各个元件对应引脚连接起来;
⑤ 检查电路板是否焊接正确,连接试验箱与焊接完成的电路板,运行电梯控制代码,调试电梯正确运行,完成实验。
2)设计方案
根据实验内容需要2个开关确定上楼和下楼状态,6个开关用于选择楼层。电梯的所处楼层用6个发光二极管表示,另外用1个发光二极管表示电梯门开关(亮灯开门、灭灯关门)。需用一块数码管显示电梯将要到达的目的楼层。同时,需要一块8255接口芯片,将其C口作为输入端,接收8个开关状态信号;将其A口作为输出端,用于向发光二极管输出电梯所处楼层信息(电梯所处楼层亮灯,其他楼层灭灯);将其B口作为输出端,用于向数码管输出目的楼层信息,使数码管显示目的楼层(无人乘坐电梯时,即没有目的楼层时,数码管显示F,表示电梯处于空闲状态)。
当乘客乘坐电梯时可选择上下楼和对应楼层,如果输入非法(上下楼开关同时打开,或没有选择楼层等)则电梯不响应乘客操作,等待正确输入。乘客输入正确时,将在数码管上显示目的楼层,通过发光二极管顺序亮灭体现电梯运行。另外,乘客一次可选择多个目的楼层,电梯将按照就近原则,顺序抵达各个楼层。由于选择开关作为电梯控制按键,开关不能自动回弹,存在硬件上的不足,电梯系统读入每次控制信息之后必须手动关闭开关。
3)程序设计
程序总体上包含两个子程序,分别为INIT子程序和RUNNING子程序。在主程序中先调用INIT子程序,再调用RUNNING子程序。INIT子程序用于初始化8255控制字、寄存器初始状态等,RUNNING子程序是电梯运行的控制程序,实现电梯运行逻辑。另外SLEEP子程序用于延时(确保人眼可观察到发光二极管的顺序亮灭过程);WRITEA子程序用于写A口,将电梯所处楼层信息输出到发光二极管;WRITEB子程序用于写B口,将目的楼层信息输出到数码管;READ子程序用于读C口,将开关状态读入;FREE子程序用于在数码管上显示F;OPEN子程序用于电梯开门;CLOSE子程序用于电梯关门;GATEC子程序功能为电梯开门并等待一段时间后关门,电梯每次到达目的楼层时执行;WHICHUP和WHICHDOWN分别用于确定上楼和下楼的目的楼层,这两个子程序在结构和功能上大体相同,只是执行过程中移位方向不同(下文将主要说明WHICHUP子程序,并简要说明与WHICHDOWN子程序的不同)。
SLEEP子程序:
将AL作为入口参数,用于确定内层循环执行多少次,内存循环每执行一次AX减1,内层循环置CX为0FFFFH,使用LOOP指令循环以达到延时的目的。SLEEP子程序流程图如下:
WRITEA子程序:
MOV AL, CL
MOV DX, 0600H
OUT DX, AL
以上为WRITEA子程序的主要代码,该子程序将CL作为入口参数(在后续代码中,为避免寄存器使用混乱,固定用CL寄存器作为电梯发光二极管亮灭的控制寄存器,将电梯所处楼层信息和开关门信息存储在CL中),该子程序实现将CL中的值由A口输出到发光二级管。
WRITEB子程序:
MOV AL, [BX + SI]
MOV DX, 0602H
OUT DX, AL
以上为WRITEB子程序的主要代码,该子程序将SI作为入口参数,BX在INIT子程序中会被赋值为NUM偏移地址。改变SI的值,通过基址变址寻址方式,将不同数值由B口输出到数码管,实现数码管显示目的楼层。
READ子程序:
MOV DX, 0604H
IN AL, DX
以上为READ子程序的主要代码,该子程序将AL作为出口参数,从C口读入开关状态到AL。
FREE子程序:
MOV SI, 0
CALL WRITEB
以上为FREE子程序的主要代码,该子程序功能简单,只是将F显示在数码管。
OPEN子程序与CLOSE子程序:
OR CL, 10000000B AND CL, 00111111B
CALL WRITEA CALL WRITEA
左侧代码为OPEN子程序主要代码,对CL进行的或运算将最高位置1控制亮灯,表示开门,而同时不会影响低6位楼层显示;右侧代码为CLOSE子程序主要代码,对CL进行的与运算将最高位置0控制灭灯,表示关门,同时也不会影响低6位楼层显示。
GATEC子程序:
CALL OPEN
PUSH AX
MOV AL, 10
CALL SLEEP
POP AX
CALL CLOSE
GATEC子程序结构简单,调用了OPEN子程序开门,接着调用SLEEP子程序延时等待一段时间,然后调用CLOSE子程序关门。
WHICHUP子程序:
由于乘客选择上下楼和楼层之后需要在数码管显示目的楼层,所以须先确定目的楼层需要在当前楼层上或者下几层楼。该子程序以DL为入口参数,以DL和AX为出口参数,将对应位置1的目的楼层信息事先存入DL,每到达一层,DL中已到的目的楼层会被置0,AX中则存放需要在当前楼层上或者下几层楼的数值信息。每次调用该程序,确定一个目的楼层。
由于CL固定用于控制发光二极管,所以使用AL右移(下楼则AL左移)代替CL左移(右移),当AL与CL对应位都为1时,与运算结果不为0,表示找到目的楼层,每次移位AH加1,用于计数。若是移位6次仍未找到目的楼层,说明所有目的楼层已经都被找到。最后将AL中与CL对应为1的位置0,表示已经到达过该目的楼层。再将AL左移恢复(下楼为右移),将AL的值赋给DL用于进行下一次判断,将AH的值赋值给AX,与SI位数统一便于相加。
INIT子程序:
INIT子程序主要用于确定8255控制字,以及寄存器赋初值。上图中10001001B控制字确定将A口和B口用于输出,C口用于输入。NUM数组已在数据段给出。
RUNNING子程序:
由于篇幅所限且上楼和下楼控制逻辑基本一致,故流程图中省略了下楼部分,主要说明上楼部分。
该子程序循环从8255接口芯片C口读入开关状态,将数值读入AL,先判断低6位是否有输入,若无输入电梯进入空闲状态,等待输入,否则继续判断上楼还是下楼,上楼则跳转到上楼代码执行,下楼跳转到下楼代码执行,若上下楼同时选择或同时不选择,则电梯进入空闲状态,等待输入。
执行上楼代码先调用WHICHUP子程序(下楼调用WHICHDOWN子程序)确定目的楼层,并将SI加AX(下楼SI减AX),在数码管显示目的楼层。判断AX是否为0,若不为0, CL左移1位(下楼右移),调用WRITEA子程序,显示在发光二极管,AX减1。每次移位后调用SLEEP子程序延时;若为0,则说明到达目的楼层,调用GATEC子程序自动开关门,接着继续判断下一个目的楼层。若所有目的楼层都已到达过,则电梯进入空闲状态,等待输入。
4) 试验箱连接测试与proteus仿真
图6为试验箱连线后运行电梯控制系统处于初始状态时,此时电梯处于第一层,第一个发光二极管被点亮,数码管显示F,电梯处于空闲状态。图中系统总线单元的XD0XD7连接8255的D0D7,用于数据传送,IOW、IOR分别连接8255的WR和RD,IOY0连接CS进行片选,XA1、XA2连接A0、A1,因此8255对应端口地址应为A口:0600H,B口:0602H,C口:0604H,D口:0606H。开关与C口相连用于输入,发光二极管与A口相连用于输出,数码管与B口相连也用于输出,另外数码管共阴极,一端接地。
图7为电梯从一楼上楼到达六楼时的状态,此时电梯门打开,由于刚到达六楼,数码管仍显示目的楼层为6。
图8为电梯从六楼下楼到四楼再到二楼时的状态,此时刚刚到达二楼电梯开门。由开关的状态可以看出,乘客选择了下楼,楼层为4楼和2楼。由于开关不会回弹,在电梯进行下一次运行前应即使关闭上一次的选择。
图9为proteus仿真连线图。8086RESET接地,选择最小工作方式,将8086和8255的WR、RD对应相连,由于8086数据地址线复用,需要74LS373进行地址锁存,将8086地址线A1、A2和8255的A0、A1的相连。端口地址和试验箱调试时相同。8255的CS接低电平,8255默认选中;RESET接低电平,不复位。A口连接发光二极管,B口连接数码管,C口连接开关,开关一侧接地,另一侧接保护电阻,将电阻另一侧接高电平。
图10为proteus运行代码时的初始状态,即电梯处于一楼,数码管显示F,表示电梯空闲。
图11为proteus运行电梯控制系统,从一楼经过三楼到达五楼时的状态,此时电梯刚刚到达五楼,电梯门打开。
图12为电梯由五楼下楼到三楼时的状态,此时电梯门打开。
5) 电路布线与焊接
图13为电路板布线图,图中蓝线表示接地,红线表示可直接铜线连接或连接高电平,绿线表示需要带绝缘层连线。图中左上角为数码管,按照由ADP的顺序与8255PB0PB7引脚相连。右侧为6个发光二极管表示电梯楼层状态由下至上分别与8255PA0PA5引脚相连,另一端接地,中间上方为显示电梯开关门的发光二极管,与PA7引脚相连,另一端同样接地。下方为8个开关和排阻,开关上端引脚连接电阻接高电平,下端接地,中间引脚对应接8255PC0PC7引脚。另外,用排针连接8255D0D7用于接试验箱XD0XD7,同样将WR、RD、CS、A0、A1与排针相连用于接试验箱。8255的VCC引脚直接接高电平,GND、RESET直接接地。
焊接实物图正面图所示使用绿灯表示楼层,红灯表示开关电梯门,8255置于中间便于连接各个外设。右侧反面图中为方便焊接,将部分引脚直接使用铜线相连,为避免短路,重合的部分连线带绝缘层相连。铜线连接时需要格外注意,防止短路。
6) 电路板测试运行
图15–图17分别为电路板运行初始状态,即电梯位于一楼,处于空闲状态;电梯由一楼上升到五楼并开门;电梯由六楼下降到四楼并开门。图中排线与试验箱XD0~XD7相连,8255上方单线连接试验箱IOW,下方左侧两根线的左侧线连接IOR,右侧线连接IOY0为片选线,下方右侧两根线的左侧线连接XA2,右侧线连接XA1。
7) 对比说明
由以上试验箱调试、proteus仿真、接口电路板上运行结果可发现,试验箱的连线是最简单、便捷的,因为开关电阻、锁存器、接地、接高电平等在试验箱内部都已经实现,连线时无需考虑。相对地,prodeus仿真时,元件都需要自行添加,锁存器连接必须自行实现,以避免8086AD复用而造成端口选择错误等问题,另外接地、接高电平等连线也必须标出才能正确运行程序。接口电路板同样需要注意接地和接高电平,尤其是8255的RESET引脚必须接地,不进行复位。相比于试验箱和proteus仿真,接口电路板上8255的引脚并非完全按照顺序排放,连线较为复杂,需要格外注意按照指定引脚连接。而在程序运行结果以及操作方式方面,三者基本相同。不同主要集中在连线逻辑结构方面。
4.设计总结
本次实验的电梯控制系统能正确在试验箱、proteus、接口电路板上运行但在实验过程中也遇到了很多问题。
在代码方面:代码编写与调试是我主要负责的部分,起初对电梯控制的逻辑想的过于复杂,是按照现实中电梯运行进行设计的,经过思考、询问老师后发现硬件设备无法满足,只能简化控制逻辑,用一套开关控制整个电梯运行,同时这也降低了代码编写难度。另外,编写代码实现电梯运行控制时,由于考虑到需要先显示目的楼层,必须由像WHICHUP/WHICHDOWN这样的子程序确定目的楼层,故实现了上文程序设计部分所述的WHICHUP/WHICHDOWN功能。将CL和SI固定为控制发光二极管和数码管的寄存器的想法也是在实现此功能时想到的。其中关于如何判断楼层已到达过,想了很多方法,最终只能用将AL对应已到达楼层清零,并将AL左移(下楼为右移)回去的笨办法实现,此处的代码不是很简洁高效。另外上楼和下楼代码功能基本相同,可以优化为一个子程序通过送入不同参数确定上楼还是下楼。整个程序多采用子程序方式编写,结构相对清晰,可以完整实现电梯控制的功能,但也还有可以优化的空间。
在Proteus仿真方面:由于第一次使用proteus软件,不知道如何使用,通过浏览讲解PPT、网上搜索并与组内成员讨论,完成连线并运行代码。起初选择单刀单掷开关发现发光二极管默认为亮状态,闭合开关后为灭状态,经过网上搜索、询问同学后改为单刀双掷开关才和实验所用开关符合,才能正确仿真。
在电路焊接方面:起初设计时将电阻与发光二极管连接错误,询问老师后得知电阻应当接在发光二极管与地线之间,同时由于发光二极管和8255相连电压较为稳定,无需电阻也可以稳定运行,为了简化焊接电路,取消了原来与发光二极管相连的电阻。另外,焊接8255时将8255VCC引脚错误接地,导致运行时发光二极管和数码管无显示,改正连线后运行正常。
设计心得
通过本次硬件课程设计,掌握了8086CPU、电路板、可编程接口芯片以及8086汇编语言的应用,也能够应用所学知识构建一个较完整的微型计算机控制系统。体会到了理论与实践结合的重要性,感受到了用所学知识实现一些具体硬件功能的乐趣,也认识到了团队合作的重要性。其次,老师在实验过程中也给予我们很大帮助,任何问题的解答都很细致。最后关于实验环境,可能由于实验器材的使用次数过多或器材保护不是很好,导致有一些实验器材反应不灵敏,使用不方便。总而言之,本次课程设计对我有很大帮助,加深了我对微机系统的理解,也具备了一定的应用能力。
附录(源代码)
DATA SEGMENT
;定义数组便于数码管显示数值
NUM DB 71H, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 0FFH
DATA ENDS
STACK SEGMENT stack
STL DW 100H DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX, DATA
MOV DS, AX
MOV AX, STACK
MOV SS, AX
CALL INIT
CALL RUNNING
SLEEP PROC NEAR ;入口参数AL(循环次数)
PUSH CX
NEXT:
MOV CX, 0FFFFH
LOP:
LOOP LOP
DEC AL
JNZ NEXT
POP CX
RET
SLEEP ENDP
WRITEA PROC NEAR ;入口参数CL
PUSH DX
PUSH AX
MOV AL, CL
MOV DX, 0600H
OUT DX, AL ;LED灯显示
POP AX
POP DX
RET
WRITEA ENDP
WRITEB PROC NEAR ;入口参数SI
PUSH DX
PUSH AX
MOV AL, [BX + SI]
MOV DX, 0602H
OUT DX, AL ;数码管显示
POP AX
POP DX
RET
WRITEB ENDP
READ PROC NEAR ;出口参数AL
PUSH DX
MOV DX, 0604H
MOV AL, 10
CALL SLEEP
IN AL, DX ;读开关状态
POP DX
RET
READ ENDP
FREE PROC NEAR ;数码管显示F
PUSH SI
MOV SI, 0
CALL WRITEB
POP SI
RET
FREE ENDP
OPEN PROC NEAR
OR CL, 10000000B;开灯
CALL WRITEA
RET
OPEN ENDP
CLOSE PROC NEAR
AND CL, 00111111B;关灯
CALL WRITEA
RET
CLOSE ENDP
GATEC PROC NEAR
CALL OPEN ;开门
PUSH AX
MOV AL, 10 ;开门等待时间
CALL SLEEP ;等待
POP AX
CALL CLOSE ;关门
RET
GATEC ENDP
WHICHUP PROC NEAR ;入口参数DL,出口参数AX,DL
XOR AH, AH
MOV AL, DL
LOP1:
MOV DH, AL
AND DH, CL
JNZ TEND ;找到楼层跳转
SHR AL, 1 ;没找到继续移位
INC AH ;AH自增计数
CMP AH, 6
JNZ LOP1
TEND:
MOV DH, CL
NOT DH
AND AL, DH ;已到达楼层清零
PUSH CX
MOV CL, AH
SHL AL, CL ;AL恢复
POP CX
MOV DL, AL
MOV AL, AH
XOR AH, AH ;AX存储AH
RET
WHICHUP ENDP
WHICHDOWN PROC NEAR ;入口参数DL,出口参数AX,DL
XOR AH, AH
MOV AL, DL
LOP2:
MOV DH, AL
AND DH, CL
JNZ TEND1
SHL AL, 1
INC AH
CMP AH, 6
JNZ LOP2
TEND1:
MOV DH, CL
NOT DH
AND AL, DH
PUSH CX
MOV CL, AH
SHR AL, CL
POP CX
MOV DL, AL
MOV AL, AH
XOR AH, AH
RET
WHICHDOWN ENDP
INIT PROC NEAR ;初始化控制字和寄存器
MOV DX, 0606H
MOV AL, 10001001B
OUT DX, AL
LEA BX, NUM
XOR CX, CX
XOR SI, SI
MOV CL, 0FFH
CALL WRITEA
MOV SI, 7
CALL WRITEB
PUSH AX
MOV AL, 10
CALL SLEEP
POP AX
MOV CL, 01H ;电梯开始处于一楼
MOV SI, 0001H
CALL WRITEA
CALL FREE
PUSH AX
MOV AL, 10
CALL SLEEP
POP AX
RET
INIT ENDP
RUNNING PROC NEAR
RERUN:
CALL FREE
CALL READ
MOV AH, AL
AND AL, 00111111B
MOV DL, AL
CMP DL, 0 ;判断楼层是否选择
JZ RERUN
AND AH, 11000000B
CMP AH, 10000000B
JZ UP ;上楼跳转
CMP AH, 01000000B
JZ DOWN ;下楼跳转
JMP RERUN
UP:
CALL WHICHUP ;确定目的楼层
CMP AX, 6
JZ RERUN
ADD SI, AX
CALL WRITEB ;显示目的楼层
NEXTU:
CMP AX, 0
JZ NEXTU1
SHL CL, 1 ;上升一层楼
CALL WRITEA ;LED显示
PUSH AX
MOV AL, 10
CALL SLEEP ;延时
POP AX
DEC AX
JNZ NEXTU
NEXTU1:
CALL GATEC ;自动开关门
PUSH AX
MOV AL, 10
CALL SLEEP ;延时
POP AX
JMP UP
DOWN:
CALL WHICHDOWN
CMP AX, 6
JZ RERUN
SUB SI, AX
CALL WRITEB
NEXTD:
CMP AX, 0
JZ NEXTD1
SHR CL, 1
CALL WRITEA
PUSH AX
MOV AL, 10
CALL SLEEP ;延时
POP AX
DEC AX
JNZ NEXTD
NEXTD1:
CALL GATEC
PUSH AX
MOV AL, 10
CALL SLEEP ;延时
POP AX
JMP DOWN
RET
RUNNING ENDP
CODE ENDS
END START
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)