资源描述
东南大学吴健雄学院微机课程设计电梯控制器
《微机实验及课程设计》报告
东南大学吴健雄学院
《微机实验及课程设计》
课程设计报告
FBI Warning:
汇编代码是好几届之前的一个学姐的,我只是修改了一下.修改后完美运行
报告是我自己写的
转载不需要注明出处,就说是你写的
姓 名: 学 号:
专 业: 吴健雄学院 实 验 室: 计算机硬件实验室
组 别: 同组人员:
设计时间: 2012 年 5 月 17 日 —— 2012 年 6 月 6日
评定成绩: 审阅教师:
目 录
一.课程设计目的与要求……………………………………………………………………2
二.方案论证与原理设计………………………………………………………………………3
三.详细(机理)设计………………………………………………………………………3
四.方案实现与测试(或调试)……………………………………………………………6
五.分析与总结………………………………………………………………………………7
一. 课程设计目的与要求
设计目的:
微机课程综合设计用于检验和提高学生在原理与接口综合应用方面分析问题与解决问题的能力,同时也给学生提供更多、更好的训练机会,课程给出了10 道微机硬件应用综合测试题。为完成每道测试题,至少需要选用TPC 微机实验装置中三部分以上的硬件电路(还需将它们有机组合起来)并编制相应的应用。
通过试验还能够让学生更好的了解所学知识在实际控制中的运用,增加对本专业的认识和学习兴趣。
设计要求:
1)设计基本要求
用键盘、按钮、八段码和LED 模拟电梯工作过程。楼层设为8 层,键盘数字键1~8 用来键入希望停的楼层,8 个LED 显示希望停的楼层,2 位八段码指示电梯当前所在楼层,按钮用来启、停电梯。电梯正常运行时以每2 秒1层的速度上升或下降。要求“电梯”能按以下方式运行:
(1)设当前电梯停在某层(2 位八段码显示相应楼层,8 个LED 全灭)。键入1~8 数字键,如键入的数字与当前电梯停层同,则什么亦不动作,若不同则相应楼层的LED 亮;如再按运行键,则电梯自动判别上升或下降(在运行过程中八段码显示楼层变化)一直到达希望停的楼层(八段码显示该楼层,相应LED 灭);
(2)设当前电梯正在上升或下降运行(此时八段码显示楼层变化,LED 指示希望抵达的楼层),若键入新的希望停的楼层数字(相应的LED 亮),则对同方向(上升或下降)未到的楼层能停,对其它情况则先停原希望停的楼层,然后按运行键后继续运行)。如下几例:
① 设电梯当前在2 层,向上运行,LED 指示希望在6 层停,此时若键入4,则电梯将在4 楼停,若再按运行键,则继续运行至6 层停;
② 同上情况,若键入的不是4 而是8,则电梯将先停在6 层,再按运行键,运行至8 层停;
③ 同上情况,若键入的不是4(或8),而是1,则电梯先停在6 层,再按运行键,运行至1层停。
2)进一步设计要求
除运行按钮外,再设计几个按钮,模拟更多的电梯运行功能,如:
① 同步在8*8 点阵显示器显示上升与下降箭头,当停止时显示当前所在楼层号.
② 直达按钮。若按此按钮,电梯按直达方式运行,即对运行期间新键入的停靠楼层(即使是同方向未到楼层)亦不停,直达终点楼层;
③ 急停按钮。电梯运行中,若按此按钮,则电梯立即停在下一到达的楼层;
断电待修按钮。按下该钮电梯不能工作,再按一下才能重新工作;
设置急停开关(K0-K7 至一),引入中断处理,立即响应,就近停靠;
分工情况:
我跟XXX一组,我主要负责程序框架的构建和大部分代码的编写,XXX负责其他的程序编写和硬件连接等工作。
二.方案论证与原理设计
我们在成熟考虑程序的整体要求和框架后,决定把程序总共分为四个模块,分别为电梯运行模块,电梯接受请求判断模块,显示模块,计时模块。
电梯运行模块是整个程序的主模块,其主要功能就是判断电梯的运行方向和停靠所要去楼层的优先顺序。电梯接受请求判断模块主要是应急停,直达,等待维修等命令。计时模块用于对系统每二秒停一楼层的计数。显示模块则包括所要到的楼层的显示和运行过程中所到楼层的实时显示。
有8个楼层,需要用8个按键模拟电梯中的请求按钮;
当电梯静止状态时,无论外部哪一层有请求,电梯都由静止状态转入向上或向下运行的状态,直到到达请求的楼层;当电梯处于向上运行的状态时,此时高于该楼层向上的请求和内部请求级别最高,其次是所有楼层向下的请求,再次是低于该楼层向上的请求;当电梯处于向下运行的状态时则情况相反;
由于中断级别在随着电梯所处楼层的不同而变化,而且中断源比较多。所以用每一个中断源直接和中断控制器相连,需要用到多个8259A级联,很不方便。为解决这个问题,首先定义三个单字节变量REQ_U、REQ_D和REQ_IN分别存储电梯每一层向上、向下和内部的请求,每一位代表一层。例如,REQ_U为 00000110B,这代表在2层和3层有向上的请求。8253定时器每隔20ms产生一次中断,中断程序便去执行扫描键盘,当扫描到有电梯内部或者外部按键时,将请求存储到变量中。每到一个状态时再检查请求变量REQ_U、REQ_D和REQ_IN的值,根据电梯的运行方向和变量中的请求,来决定电梯下一步的运行。
设电梯的当前楼层为floor(floor=1~8),运行方向为dir(dir=0,向上;dir=1,向下),在电梯运行的工程中,用数码管输出floor值显示当前的楼层。LED输出REQ_IN的值显示电梯内已经请求的楼层。
主要的模块如下:
1.可编程定时/计数器8253
定时/计数器8253主要是用于定时20ms,触发中断进行键盘扫描。电路连线是CLOCK0接Q6,分频后频率为46875Hz,OUT0接中断IRQ2,每20ms中断一次,GATE0接5v。计数器的初值应该是3A9H;
2.8255并行接口单元
8255主要是用于数码管和发光二极管的数据输出。所以用8255B口8接8个发光二极管,A口接数码管的数据端。
3 LED点阵显示
由于提高要求需要显示上下箭头,所以使用8*8点阵显示箭头。
4 微机控制器
程序在微机上运行,通过总线控制实验箱上各部件的运行。
三.详细(机理)设计
1) 软件流程图(总流程图)
本设计的软件设计的思路:通过软件编程使8253输出定时信号申请中断,在中断服务程序中扫描键盘,如果有按键,修改相应的变量位,并输出内部请求变量REQ_IN到发光二极管显示当前的内部请求楼层。在主程序中,查询变量的值,根据电梯调度算法运行电梯。
图表 1 电梯系统总流程图
2) 电梯控制算法模块
逻辑实现:
当电梯向上运行时:
a) 位于当前层以下的向上请求都被忽略留到下次向上运行时处理。
b) 位于当前层以上的向上请求都被记录留到此次运行处理。
c) 无论哪层的向下请求都被忽略留到下次向下运行时处理。
当电梯向下运行时:
a) 位于当前层以上的向下请求都被忽略留到下次向下运行时处理。
b) 位于当前层以下的向下请求都被记录留到此次运行处理。
c) 无论哪层的向上请求都被忽略留到下次向上运行时处理。
算法实现:
dir代表电梯的运行方向,0代表电梯向上运行,1代表向下运动。设REQ_U(n)代表第n层向上的请求,同样,REQ_D(n) 代表第n层向下的请求,REQ_IN(n) 代表第n层内部的请求。求next的方法为:电梯向上时,next为内部请求的最小值和向上请求的大于floor的最小值之间的小者。电梯向下时,next为内部请求的最大值和向下请求中小于floor的最大值之间的大者。没有满足要求的时返回0。
图表 2 电梯控制算法流程图
3) LED显示程序:本设计只用到了一个LED,只要将floor转换为相应的段码。先输出位码,再输出段码,循环输出就可以动态显示。为了循环的显示,将LED显示程序放在中断服务程序中。(将“楼层”作偏移码,利用XLAT,很简单就可以实现译码)
图表 3 电梯按键、显示中断流程图
VCC
4) 硬件连接图
280H
28bH
1MHz
/CS
PA0-7
PB0-7
PC0
8255
/CS CLK0
GATE0
OUT0
CLK1
GATE1
OUT1
8253
八段码数码管
LED小灯
急停开关
四. 方案实现与测试(或调试)
首先根据设计思路,选择采用8253和8255芯片,规避了使用较为复杂的中断。然后调试硬件,确定位选、芯片等工作正常。这可以通过手动输入控制字,进行简单输入输出实现。然后确定8253、8255芯片的地址,开始软件编程。
软件编程首先完成整体的逻辑框架,然后具体编写子程序。刚开始时采用软件延时,优先调试8255。采用8255的A、B口的0方式,A、B口的变化将反映在八段码和LED灯上。子程序的编写即将设计好的算法转换为程序流,用程序流的方向实现选择,用调用子程序实现具体操作。 然后加入8253的硬件延时,将OUT1连至PC0,通过不断查询PC0口的状态进行延时。由于前面8255已经调好,所以8253的调试比较顺利。
最终将全部硬件连线接好,进行整机联调。当中发现许多问题,首先利用示波器排除硬件故障,再回过头来对软件进行单步,这时由于有现象,进行软件调试的时候也更有针对性。通过设置断点,逐步跟踪寄存器值,经过几次的修改之后,成功实现了预定方案。
由于数码管和LED灯显示都是采用查表法,根据输入字符的ASCII码查表得到输出,有时出现LED不正常亮灭的现象,是在查表时出错,比如没有减去31H,就会使灯的显示杂乱无章。
实物连接图:
五.分析与总结
1)设计要求每次电梯开关时间为2秒,而一开始我们无法保证精确的时间。后来经过讨论后发现可以用8253计数器达到此功能,我们翻阅书籍后分别用方式3和方式0实现了精确2秒的要求。
2) 编程中遇到的大多是逻辑问题.另一个经常遇到的问题就是跳转语句超出范围的错误,这个错误的解决是通过改变语句的顺序,如实在无法通过改变顺序来消除错误,则通过二次跳转,即跳过中间过程再跳至目标。
3) 我们写的电梯程序,d的意义为当前楼层,当输入要去的楼层bl时,判断bl与cl的大小关系,假设bl>cl,则程序先把cl加1,再延时两秒,再比较bl与cl的大小是否相等,如果相等则跳出,不等则把cl加1,再延时,再判断。
4) 当在上行过程中再输入另一个想去的楼层ch时,则跳转至 ch处理过程。因为是在延时前就把cl加1了,因此在这上行两秒内,cl已经上了一层了。因此就必须判断ch以及bl是否与此时的cl相等,如相等则在即将到达的这一层停。由于一开始我们来判断bl与cl是否相等,导致如果在即将到bl层的时候按下ch则会使cl不断增大,即ASCII 码不断增大,又返回至0,又增大至bl 才停止。
5) 另外一个问题就是8个LED显示要去哪个楼层的问题。我们是用数据DD0—DD7接到74LS273输出的。bl,ch同时要被显示。我们于是就把bl,ch的0,1,2,3,…..8分别对应于0B,1B,10B,………10000000B,然后把两者相加就能显示了。如果到达bl则把bl赋为0,则对应灯灭。如果到达ch,则把ch赋为0,则ch对应楼层灯灭。现在如果输入ch等于bl,按要求是对应灯亮,到该层停,而实际上变成上一层灯亮,因为ch与bl对应二进制相加,产生进位。解决方法是,如果bl,ch相等,则先把cl 复位为0,然后再调用LED显示。
6)电梯这个题目的特点就是状态多,各种大小循环相互嵌套,很难写代码。但是,由于每一层的代码都是相似的,在调试出某一层之后,其他七层的代码也很好写。
在设计过程中我们遇到了很多问题,而汇编语言本身不是像高级语言一样直观和简洁,刚开始走了不少弯路,但不断调试和查资料之后感觉好多了,程序的编写速度也大大加快了。
实验过程中,我不断翻书,巩固了上课没听懂的知识,加深了对各个芯片的直观的印象,也培养了细心实验的能力。
参考书目:
[1] 杨素行等,《微型计算机系统原理及应用》,北京,清华大学出版社,2009年
[2] 东南大学微机系统与接口课程组,《微机实验及课程设计教程试用版3.0》,南京,东南大学出版社,2010年
附录.代码程序
data segment
ioport equ 0ec00h-0280h
io8253a equ ioport+280h;0计数端口计数为10000,方式3
io8253b equ ioport+281h;1计数端口计数为200,方式0
io8253c equ ioport+283h;8253控制端
;shangmian shi 8253
io8255a equ ioport+288h;8255控制端以及a,b,c端口地址
io8255b equ ioport+289h
io8255c equ ioport+28ah
io8255 equ ioport+28bh
proth equ ioport+290h;点阵灯显示,行阵
protlr equ ioport+298h;点阵灯显示,列阵
number db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh;七段码
min db 00h,01h,02h,03h,04h,05h,06h,07h;点阵的行
;buff1 db 10h,30h,7fh,0ffh,0ffh,7fh,30h,10h;向上箭头
buff1 db 10h,20h,40h,0ffh,0ffh,40h,20h,10h
;buff2 db 08h,0ch,0feh,0ffh,0ffh,0feh,0ch,08h;向下箭头
buff2 db 08h,04h,02h,0ffh,0ffh,02h,04h,08h
buff3 db 00h,00h,00h,00h,00h,00h,00h,00h
menu db '************************************************',0DH,0AH
db '* DianTiKongZhiQi---elevator *',0Dh,0Ah
db '* 61010207 Jia Xiawen *',0DH,0AH
db '* 61010317 Yu Hailei *',0Dh,0Ah
db '************************************************',0Dh,0Ah
db 'input a number to go to the corresponding level',0DH,0AH
db 'esc----------exit',0DH,0AH
db 'enter--------go',0DH,0AH
db 'z------------go directly',0Dh,0Ah
db 'x------------quickstop',0Dh,0Ah
db 'c------------waiting for fixing',0Dh,0Ah
db '280H----8253CS',0Dh,0Ah
db '1MHz----8253_clk0',0Dh,0Ah
db 'VCC----8253_gate0',0Dh,0Ah
db '8253_clk1----8253_out0',0Dh,0Ah
db '8253_gate1----K0',0Dh,0Ah
db '8253_out1----8255_PC0',0Dh,0Ah
db '28bH----8255_cs',0Dh,0Ah
db 'PA0~7----SHU MA GUAN',0Dh,0Ah
db 'PB0~7----led0~7',0Dh,0Ah
db 'MOVE!',0Dh,0Ah ,'$'
data ends
stacks segment stack
db 100 dup (?)
stacks ends
code segment
assume cs:code,ds:data,ss:stacks
start:
mov ax,data;初始化
mov ds,ax
mov dx,offset menu;打印菜单,说明硬件电路的连接等
mov ah,09
int 21h
mov dx,io8255;8255初始化,a、b输出,c口输入
mov al,89h
out dx,al
mov bl,31h;bl代表当前电梯所在楼层,初始值设为1
main: mov al,0
call shownumber;显示当前楼层
mov cl,0;cl为第一次输入的要去的楼层
mov ch,0;ch为在中途中再次输入的要去的楼层
call showled
mov ah,01;通过键盘输入第一次要去得楼层cl
int 21h
cmp al,1bh;是esc则退出
je exit
cmp al,31h;键入的数字是否在1-8之间,如不是重新输入
jl main
cmp al,38h;跟8比较,如果比8大,则循环输入
jg main
mov cl,al
call showled;8个led灯显示cl对应的楼层
cmp cl,bl;cl与bl比较
je main;相等则返回重新输入
jg up;大于则向上运行
jl todown;小于则向下运行
exit: mov ah,4ch
int 21h
;---------------------------------------------------------------------------------电梯上行
up: call judge;电梯上行的情况
up1: add bl,1
call updelay;调用向上运行延时子程序,出现向上的箭头
call shownumber;调用显示子程序,通过数码管显示当前楼层bl
cmp bl,cl;bl,cl不等则继续
je main;相等则返回
jmp up1
upgetch:mov ah,1;在上升过程中如果有其他的键按下时
int 21h
cmp al,78h;判断是否为急停键x
je jit
cmp al,63h;判断是否为断电待修键c
je duandian
cmp al,31h;数字是否在1-8之间如不是继续上行
jl gotoup
cmp al,38h
jg gotoup
mov ch,al
call showled
call delayup
call shownumber
call judgeequ;判断当前楼层与第一次要去的楼层是否相同
cmp ch,bl;比较ch与bl的区别
je loucengxiangdeng;相等则在该层停,等待运行信号输入
jl xianshanghouxia;ch小于bl则先上行至cl在下行至ch
cmp ch,cl;ch大于bl则在判断ch与cl的大小关系
je xiangdengup;相等则一直上行至cl
jl sameup;ch大于bl小于cl则先上行到ch在上行到cl
jg tosameup2;ch大于cl则先上行到cl在上行到ch
gotoup:call delayup
jmp up1
duandian: mov al,0;上升时遇到了断电的情况,则等待键入,除非再次键入的为c才继续运行
mov ah,7
int 21h
cmp al,63h
jne duandian
call delayup
call shownumber
jmp up1
jit: call delayup;上升时遇到了急停的情况,则停在下一层,然后回到main
call shownumber
jmp main
todown: jmp down
updelay proc near;向上运行的延时子程序
call delayfirst;用于初始化8253
push dx
call cleardots ;调用使其能够清零
updelay1:call dotsup;循环调用向上的箭头显示
mov ah,1;键盘是否有输入
int 16h
jne upgetch;如有则跳转到输入处理
mov dx,io8255c;8255c口输入,看2s延时是否结束
in al,dx
and al,01;是否计时结束
jz updelay1
pop dx
ret
updelay endp
tomain: jmp main
tosameup2:jmp sameup2
;---------------------------------------------------------------------------------上行中遇到的各种情况列举
loucengxiangdeng:call shownumber;第二次要去得楼层与当前楼层相同,直接停在该层
mov ch,0
call showled
call stop2
call upcl
jmp main
xianshanghouxia:call showled;先上行到cl再下行到ch
call upcl
mov cl,0
call showled
call stop2
call downch
jmp main
xiangdengup:mov ch,0;二次要去的楼层与第一次要去的相同,直接上行到第一次要取得楼层
call showled
call upcl
jmp main
sameup:call showled;同方向的楼层,先上行到ch再上行到cl
call upch
mov ch,0
call showled
call stop2
call upcl
jmp main
sameup2:call showled;同方向的楼层,先上行到cl再上行到ch ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;------------------------
call upcl
mov cl,0
call showled
call stop2
call upch
jmp main
jittt: jmp jit
;----------------------------------------------------------电梯下行,与电梯上行的情况基本类似,稍作修改即可
down: call judge
down1: sub bl,1
call downdelay
call shownumber
cmp bl,cl
je tomain
jmp down1
downgetch:mov ah,1
int 21h
cmp al,78h
je jit1
cmp al,63h
je duandian1
cmp al,31h
jl gotodown
cmp al,38h
jg gotodown
mov ch,al
call showled
call delaydown
call shownumber
call judgeequ
cmp ch,bl
je stopdowncl
jg downclupch;ch大于bl则先下行至cl在上行至ch
cmp ch,cl;ch小于bl则在判断ch与cl的大小关系
je jmpdowncl;相等则一直下行至cl
jl downcldownch;ch小于bl小于cl则先下行到cl在下行到ch
jg todownchdowncl;ch大于cl则先下行到ch在下行到cl
gotodown:call delaydown
jmp down1
duandian1: mov al,0;下降遇到了断电的情况,则等待键入,除非再次键入的为c才继续运行
mov ah,7
int 21h
cmp al,63h
jne duandian1
call delaydown
call shownumber
jmp down1
jit1: call delaydown;下降时遇到了急停的情况,则停在下一层,然后回到main
call shownumber
jmp main
downdelay proc near;向下运行延时子程序,与向上运行延时子程序大体相同
call delayfirst
push dx
call cleardots;调用使其能够清零
ddy: call dotsdown;循环调用向下的箭头显示
mov ah,1
int 16h
jne downgetch
mov dx,io8255c
in al,dx
and al,01
jz ddy
pop dx
ret
downdelay endp
todownchdowncl:jmp downchdowncl
;---------------------------------------------------------------------------------下行中遇到的各种情况列举
stopdowncl:call showled
mov ch,0
call showled
call stop2
call downcl
jmp main
downclupch:call showled
call downcl
mov cl,0
call showled
call stop2
call upch
jmp main
jmpdowncl:mov ch,0
call showled
call downcl
jmp main
downcldownch:call showled
call downcl
mov cl,0
call showled
call stop2
call downch
jmp main
downchdowncl:call showled
call downch
mov ch,0
call showled
call stop2
call downcl
jmp main
;--------------------------------------------------------------------电梯上、下行中遇到的各种情况处理方法
jitt: jmp jittt
judgeequ proc near ;判断当前楼层与第一次要去的楼层的关系
cmp cl,bl
jne back
cmp cl,ch
je clequch
mov cl,0
call shownumber
call showled
call stop2
cmp ch,bl
jg upchhere
jl downchhere
upchhere:call upch
jmp main
downchhere:call downch
jmp main
clequch:mov ch,0
call showled
call onlydelay;
jmp main
back: ret
judgeequ endp
upcl proc near;上行到cl的子程序
upcl1: inc bl
call dirdelay1
call shownumber
cmp bl,cl
jl upcl1
ret
upcl endp
jitt1: jmp jit1
upch proc near;上行到ch的子程序
upch1: add bl,1
call dirdelay1
call shownumber
cmp bl,ch
jl upch1
ret
upch endp
downcl proc near;下行到cl的子程序
downcl1:sub bl,1
call dirdelay2
call shownumber
cmp bl,cl
jg downcl1
ret
downcl endp
downch proc near;下行到ch的子程序
downch1:sub bl,1
call dirdelay2
call shownumber
cmp bl,ch
jg downch1
ret
downch endp
;----------------------------------------------------------------------直接上下行时对按键情况的处理
stop2 proc near;没有直达键的暂停子程序
gostop2:mov al,0
mov ah,1
int 21h
cmp al,13
jne gostop2
mov al,0
ret
stop2 endp
dirgetch1:mov ah,1;直接上行对按键的处理
int 21h
cmp al,63h
je dirduandian1
cmp al,78h
je jit21
jmp dirback1
dirgetch2:mov ah,1;直接下行对按键的处理
int 21h
cmp al,63h
je dirduandian2
cmp al,78h
je jit22
jmp dirback2
jit21: call delayup;
call shownumber
jmp main
jit22: call delaydown;
call shownumber
jmp main
dirduandian1:mov al,0;直接上行时遇到了断电待修的情况
mov ah,1
int 21h
cmp al,63h
jne dirduandian1
call delayup;
call shownumb
展开阅读全文