资源描述
资料内容仅供您学习参考,如有不当或者侵权,请联系改正或者删除。
微机原理与接口技术
课程设计报告
专 业:
班 级:
姓 名:
学 号:
指导教师评语:
成绩: 签名:
年 月 日
小键盘按键识别
一. 课题任务与要求
实验箱上有一个24键小键盘, 出厂时按键接点已经按图所示连接。小键盘有8根横向引出线。实验前将8根横向引出线与PA0~PA7相连, 3根纵向引出线与PB0~PB2相连, 再从”I/O口地址译码器”选择一个译码器输出连接到8255的片选端, 做好上述连接之后, 就构成了以8255为核心的键盘输入电路要求:
在实际的自动控制系统中, 键盘输入电路的作用是输入数据( 0~9, A~F) 或者输入控制信号( G, M, P, R, W, X, Y, S) 。实现上述功能的核心程序是”按键识别”。
本实验要求设计按键识别程序, 当按下小键盘上某一个键的时候, 主机屏幕显示闭合键的键名, 按下小键盘”R”键之后停止演示。
二.完成任务的方法或方案简介
本程序显示数字0到9, 刚刚开始提出两中解决方案一是用跳转法直接显示数值, 二是用查找法间接显示数值, 本程序是用第一种方案, 虽然程序多了些, 但直观容易理解, 故采纳第一种方案。
DISPLAY函数用来将BUFFER中的键值显示在数码管上。
设定A口方式0输出,B口方式0输入。
GETINPUT函数经过行值和列值查出输入的键值, 并将它保存在AL中, 如果输入是R,则AL赋值为FFH; 如果输入非法字符, 则AL赋值为0AH。
设定如果是R则退出程序.
CHANGE函数用来改变BUFFER中保存的键值, 将BUFFER中的键值移位, 最后一位加入AL中的新键值。
CLOSEALL此函数用在退出程序时将数码管关闭.
以上是主题函数, 在设计过程中还碰到了一些细节问题, 例数码管的显示才用延迟20MS的办法解决, 具体方案在DISPLAY函数中。
三.实现系统
1、 程序框图:
预置: A口为方式0输出
B口为方式0输入
0 PA7-------PA0
PB2----PB0 AH
AH=7?
延时20ms
预置: B口为方式0输出
A口为方式0输入
列值 PB2-PB0
PA7-PA0 AL
根据AX内容, 查找键值表, 显示相应的键值。
是R?
结束演示
2、 实验电路图:
3、 8255方式选择控制字
1
D6
D5
D4
D3
D2
D1
D0
C下半口 IO:
1=输入
0=输出
A组方式:
00=方式0
01=方式1
1X=方式2
方式选择控制字标志
B口IO:
1=输入
0=输出
B组方式:
0=方式0
1=方式1
C上半口IO:
1=输入
0=输出
A口 IO
1=输入
0=输出
4、 源程序:
TITLE LITTLEKEYBOARD
SSEG SEGMENT PARA STACK 'STACK'
DB 256 DUP (0)
SSEG ENDS
DSEG SEGMENT
A_8255 EQU 210H
B_8255 EQU 211H
CON_8255 EQU 213H
BUFFER DB 6 DUP(0)
HANG DB ?
LIE DB ?
NEWHANG DB ?
NEWLIE DB ?
TABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG, DS:DSEG,SS:SSEG
START PROC NEAR
MOV AX,DSEG
MOV DS,AX
CALL CLOSEALL
(关掉数码管, 防止因为最初数码管有显示而使程序执行不正常。)
CMPAGAIN:
CALL DISPLAY
(DISPLAY函数用来将BUFFER中的键值显示在数码管上。)
MOV DX,CON_8255
MOV AL,10000010B
OUT DX,AL
( 设定A口方式0输出,B口方式0输入)
AGAIN:
CALL DISPLAY
MOV DX,A_8255
MOV AL,0
OUT DX,AL ( 0->PA7---PA0)
MOV DX,B_8255
IN AL,DX
AND AL,00000111B (取出PB0-PB2
CMP AL,00000111B
JE AGAIN
MOV LIE,AL( 将列值保存)
CALL DELAY1( 延时20ms)
MOV DX,CON_8255
MOV AL,10010000B
OUT DX,AL
( 预置A口方式0输入, B口方式0输入)
MOV DX,A_8255
IN AL,DX
MOV HANG,AL( 将行值保存)
CALL GETINPUT
( GETINPUT函数经过行值和列值查出输入的键值, 并将它保存在AL中, 如果输入是R,则AL赋值为FFH; 如果输入非法字符, 则AL赋值为0AH。)
CMP AL,0AH
JE CMPAGAIN
( 如果是非法字符则跳回)
CMP AL,0FFH
JNE CONTINUE
( 如果是R则退出程序.)
CALL CLOSEALL
MOV AH,4CH
INT 21H
CONTINUE:
CALL CHANGE
(CHANGE函数用来改变BUFFER中保存的键值)
MOV DX,CON_8255
MOV AL,10000010B
OUT DX,AL
( 设定A口方式0输出,B口方式0输入)
LLL:
CALL DISPLAY
MOV DX,B_8255
IN AL,DX
AND AL,00000111B
(取出PB0-PB2)
CMP AL,00000111B
JNE LLL
JMP CMPAGAIN
(不断扫描,如果不松开按键, 那么就循环等待; 直到按键松开就跳回。)
RET
START ENDP
;*********************************
( 此函数用以延时20MS)
DELAY1 PROC NEAR
PUSH AX
PUSH CX
PUSH DX
MOV AH,86H
MOV CX,0
MOV DX, 0
INT 15H
POP DX
POP CX
POP AX
RET
DELAY1 ENDP
;********************************
( GETINPUT函数经过行值和列值查出输入的键值, 并将它保存在AL中, 如果输入是R,则AL赋值为FFH; 如果输入非法字符, 则AL赋值为0AH。)
GETINPUT PROC NEAR
CMP LIE,00000110B
JE LIE0
CMP LIE,00000101B
JE LIE1
CMP LIE,00000011B
JE LIE2
MOV AL,0AH
RET
LIE2:CMP HANG,00010000B
JE NEXT
MOV AL,0AH
RET
NEXT:MOV AL,0FFH
RET
LIE0:CMP HANG,01111111B
JE KEY8
CMP HANG,10111111B
JE KEY9
MOV AL,0AH
RET
KEY8:MOV AL,8
RET
KEY9:MOV AL,9
RET
LIE1:CMP HANG,01111111B
JE KEY0
CMP HANG,10111111B
JE KEY1
CMP HANG,11011111B
JE KEY2
CMP HANG,11101111B
JE KEY3
CMP HANG,11110111B
JE KEY4
CMP HANG,11111011B
JE KEY5
CMP HANG,11111101B
JE KEY6
CMP HANG,11111110B
JE KEY7
MOV AL,0AH
RET
KEY0:MOV AL,0
RET
KEY1:MOV AL,1
RET
KEY2:MOV AL,2
RET
KEY3:MOV AL,3
RET
KEY4:MOV AL,4
RET
KEY5:MOV AL,5
RET
KEY6:MOV AL,6
RET
KEY7:MOV AL,7
RET
GETINPUT ENDP
;**********************************
(CHANGE函数用来改变BUFFER中保存的键值, 将BUFFER中的键值移位, 最后一位加入AL中的新键值。)
CHANGE PROC NEAR
PUSH AX
PUSH SI
MOV SI,OFFSET BUFFER
MOV AH,[SI+1]
MOV [SI],AH
MOV AH,[SI+2]
MOV [SI+1],AH
MOV AH,[SI+3]
MOV [SI+2],AH
MOV AH,[SI+4]
MOV [SI+3],AH
MOV AH,[SI+5]
MOV [SI+4],AH
MOV [SI+5],AL
POP SI
POP AX
RET
CHANGE ENDP
;**********************************
(DISPLAY函数用来将BUFFER中的键值显示在数码管上。)
DISPLAY PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
MOV BX,OFFSET TABLE
MOV SI,OFFSET BUFFER
MOV CL,1
XUNHUAN:
MOV AL,[SI]
XLAT
MOV DX,201H
OUT DX,AL
MOV DX,200H
MOV AL,CL
OUT DX,AL
MOV DX,200H
MOV AL,0
OUT DX,AL
INC SI
SHL CL,1
CMP CL,40H
JNE XUNHUAN
POP SI
POP DX
POP CX
POP BX
POP AX
RET
DISPLAY ENDP
;*********************************
( 此函数用在退出程序时将数码管关闭.)
CLOSEALL PROC NEAR
PUSH AX
PUSH CX
PUSH DX
MOV CL,1
XUNHUAN1:
MOV DX,200H
MOV AL,CL
OUT DX,AL
MOV AL,0
OUT DX,AL
SHL CL,1
CMP CL,20H
JNE XUNHUAN1
POP DX
POP CX
POP AX
RET
CLOSEALL ENDP
CSEG END
END START
四、 程序运行结果分析:
六.实验总结:
1.实验电路板上8255的端口地址位210H-213H, 这与书上给的不一样, 开始时在这方面花费了较多时间。
2.经过此次程序设计, 我对计算机读取键盘值的过程有了一定的认识。最开始编程序时并没有想到如果始终按同一个键不放, 数码管上就会一下子出来很多字符。调试时发现了这个问题, 想到的解决方法有两种, 一种是每一次按键后检测键是否松开, 直到松开后再继续执行下一次判断; 另一种是按键后延缓一个固定的时间( 大约0.2秒) 再判断( 计算机的键盘就是采取这样的方法) 。 本程序采用的是第一种方法。
3.编程序要养成好的习惯, 我最初的程序结束时并没有关掉数码管, 以致下次用时数码管显示不正确。好的程序应该各方面想得周到一些, 例如我后来在开始和结束时都加了关闭数码管程序( CLOSEALL) , 这就避免了上述问题。
4.我并没有采用查表得方法来获得键值, 我觉得用跳转的方法能使程序的可读性强一些。当然, 程序代码会长许多, 但此法由于思路清楚, 比较容易查错。
展开阅读全文