本科实验报告
实验名称: 基于并行接口的键盘控制
实验一 基于并行接口的键盘控制
一、实验目的
1、掌握简单并行接口(8255)的工作原理及使用方法。
2、了解小键盘的工作原理,学会设计小键盘的接口技术。
3、利用8255并行接口芯片作为小键盘的接口电路,掌握它们之间的线路连接。
4、程序实现实验系统上的4×4键盘输入。
二、实验内容与步骤
1、接线: PA0-PA3 /8255 接 行0-行3 /4×4键盘
PB0-PB3 /8255 接 列0-列3 /4×4键盘
CS /8255 接 YI/IO地址
2、编程:实现在按下小键盘上的任意键后,在微机屏幕上显示相应的字符。输入输出关系如下:
小键盘 显示 小键盘 显示
0 -- 0 8 -- 8
1 -- 1 9 -- 9
2 -- 2 A -- A
3 -- 3 B -- B
4 -- 4 C -- C
5 -- 5 D -- D
6 -- 6 E -- E
7 -- 7 F -- F
三、实验原理
1、熟悉8255A-5芯片工作方式的设置
(1)基本控制字
基本控制字的格式如下:
各位含义如下:
D7:设定工作方式标识,1有效。
D6、D5:A组方式选择:00--方式0 01--方式1 1X—方式2
D4:端口A功能(1=输入,0=输出)
D3:端口C高四位功能(1=输入,0=输出)
(2)端口C置位/复位控制字
端口C置位/复位控制字如下:
各位含义如下:
D7:位置0位置1标识,0有效。
D6、D5、D4:不用,可人任意值。
D3、D2、D1:端口C的每位选择,由111—000分别表示第7位—第0位。
D0:位置1/置0,1=置1,0=置0.
2、键盘阵列由8255芯片控制,并将行列连接到8255芯片的A口、B口,还需要连接8255芯片的片选到YI/IO地址(288H~28FH),以使键盘阵列由8255芯片控制。其线路连接图如下:
3、编程方法
对于片选信号根据设置的YI/IO地址来具体连接相应的输出端口。8255A与4×4矩阵键盘接口线路如图所示。PA0-PA3分别连接矩阵键盘的4条行线,PB0-PB3分别连接矩阵键盘的四条列线。所有的行线、列线通过上拉电阻共与正电压源相连。因此当按键没有按下时,所有的端口读入的数据均为‘1’。当有按键按下时,对应的行线与列线读入的数据应保持一致。皆为‘0’或皆为‘1’。矩阵键盘的检测就是按照上述特性实现的。一共有两种检测方法:行扫描法、行反转法。
(1)键的识别—行扫描法
第一步应该判断是否有键按下
第二步判断哪一个键被按下,显示
程序参考流程如下:
(2)键的识别—行反转法
第一步应该判断是否有键按下
第二步行线输出,列线输入
第三步列线输出,行线输入
第四步判断哪一个键被按下,显示
程序参考流程如下:
图3 行反转法工作示意图
四、实验代码及注释
data segment
tab1 DB 'F', 'E', 'D', 'C'
tab2 DB 'B', 'A', '9', '8'
tab3 DB '7', '6', '5', '4'
tab4 DB '3', '2', '1', '0'
kb DB 00eh, 00dh,00bh,007h
port equ 288h
data ends
stack segment
sta db 256 dup(?)
top equ size sta
stack ends
code segment
assume cs:code,ds:data,ss:stack
main proc far
mov ax,data
mov ds,ax
mov ax, stack
mov ss,ax
mov sp,top
mov dx, port+3 ;初始化8255
mov al,10000010b
out dx,al
begin:
mov al,0
mov dx, port ;A口设置
out dx,al ;A口输出
mov dx, port+1 ;B口设置
in al,dx ;B口输出
and al,0fh ;判断是否有键按下
cmp al,0fh
je begin ;没有键按下,则继续扫描
mov al,00001110b
mov dx, port
out dx,al
mov dx, port+1
in al,dx
lea bx,tab1
cmp al,0fh
jne display
mov al,00001101b
mov dx, port
out dx,al
mov dx, port+1
in al,dx
lea bx,tab2
cmp al,0fh
jne display
mov al,00001011b
mov dx, port
out dx,al
mov dx, port+1
in al,dx
lea bx,tab3
cmp al,0fh
jne display
mov al,00000111b
mov dx, port
out dx,al
mov dx, port+1
in al,dx
lea bx,tab4
cmp al,0fh
jne display
nop
jmp begin
display:
mov di,bx
lea si,kb
next:
cmp al,[si] ;查键盘扫描码表
je show ;找到了,转去显示
inc si ;否则继续
inc di
jmp next
show: ;显示键入字符
mov ah,2
mov dl,[di]
int 21h
cmp dl, 'F' ;若是'P'则退出
je over
call delay
jmp begin ;重新开始查询
over:
mov ah,4ch
int 21h
main endp
delay proc near ;延时循环 100*65536次
push di
push cx
mov cx,0fh
mov di,0
again:
nop
dec di
jnz again
dec cx
jnz again
pop cx
pop di
ret
delay endp
code ends
end main
五、实验结果
当连接好设备、程序运行成功时,按下小键盘上的键,屏幕中会显示相应的数字或字母。按下“P”键时,则退出。
六、实验心得与体会
这次是计算机原理与应用的第一次实验,内容相对简单,但由于不是很清楚实验流程和操作方法,所以在调试程序时遇到了一些问题,通过思考和讨论成功解决。这次实验帮助我熟悉了8255A-5芯片的工作方式,在认识计算机内部结构和功能实现方式等方面有了更多的进步。
第二篇:北京理工大学微机原理四次程序
data segment
tab1 DB 'F', 'E', 'D', 'C' tab2 DB 'B', 'A', '9', '8' tab3 DB '7', '6', '5', '4'
tab4 DB '3', '2', '1', '0'
kb DB 00eh, 00dh,00bh,007h
port equ 288h
data ends
stack segment
sta db 256 dup(?)
top equ size sta
stack ends
code segment
assume cs:code,ds:data,ss:stack main proc far
mov ax,data
mov ds,ax
mov ax, stack
mov ss,ax
mov sp,top
; 初始化8255
mov dx, port+3
mov al,10000010b out dx,al
begin:
mov al,0
mov dx, port out dx,al
mov dx, port+1 in al,dx
and al,0fh cmp al,0fh je begin
;若有键按下,按列查找哪个键
mov al,00001110b
mov dx, port out dx,al
mov dx, port+1
in al,dx
lea bx,tab1 cmp al,0fh jne display
mov al,00001101b
mov dx, port out dx,al
mov dx, port+1
in al,dx lea bx,tab2 cmp al,0fh jne display
mov al,00001011b
mov dx, port out dx,al
mov dx, port+1
in al,dx lea bx,tab3 cmp al,0fh
jne display
mov al,00000111b mov dx, port out dx,al
mov dx, port+1
in al,dx lea bx,tab4 cmp al,0fh jne display
nop
jmp begin
;查找按下的键,并显示
display:
mov di,bx
lea si,kb ;存小键盘扫描码
next: cmp al,[si] ;查键盘扫描码表 je show ;找到了,转去显示 inc si ;否则继续 inc di
jmp next
show: ;显示键入字符
mov ah,2
mov dl,[di]
int 21h
cmp dl, 'F' ;若是'F'则退出 je over
call delay
jmp begin ;重新开始查询
over:
mov ah,4ch
int 21h
main endp
delay proc near
push di
push cx
mov cx,0fh
mov di,0
again:
nop
dec di
jnz again
dec cx
jnz again
pop cx
pop di
ret
delay endp
code ends
end main
;延时循环 100*65536次
p8259 equ 20h
p8255 equ 288h
p8253 equ 280h ;IO Y1 data segment
led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;数码管0-9 sec1 db 0
sec2 db 0
min1 db 0
min2 db 0
mes db 42h
Old_0A DW 0,0 Old_8259 DB 0
data ends
stacks segment
db 64 dup (0)
stacks ends
code segment
assume cs:code,ds:data,es:data
start:
mov ax,data
mov ds,ax
cli
mov al,00110110b
mov dx,p8253+3 ;计数器0,工作在模式3
out dx,al
mov ax,2710h
mov dx,p8253
out dx,al
mov al,ah ;先赋高八位 再赋低八位
out dx,al
mov al,01110110b
mov dx,p8253+3 ;计数器1,工作在模式3
out dx,al
mov ax,100
mov dx,p8253+1
out dx,al
mov al,ah ;先赋高八位 再赋低八位
out dx,al ;原中断向量
;设置中断向量表
PUSH ES
PUSH BX
MOV Al,0BH ;保护原中断向量,0B中断类型号 mov ah,35h
INT 21H ;读中断向量表
MOV Old_0A+2,ES;ES为段地址,BX为段偏移地址 MOV Old_0A,BX
POP BX
POP ES
push ds
mov al,0bh ;?写新中断向量 ?
mov ah,25h
mov dx,seg INT_0A
mov ds,dx
mov dx,offset INT_0A
int 21h
pop ds
mov al,10000000b ;对8255进行设置,PB/PC输出 mov dx,p8255+3
out dx,al
in al,p8259+1 ;8259奇地址?中断向量屏蔽 mov old_8259,al ;字设置 保护原屏蔽字 and al,11110111b ;开IRQ3
out p8259,al
sti ;开中断
play:
lea bx,led ;led段码
mov dl,sec1 ;秒个位
mov dh,0
mov si,dx
mov al,[bx][si]
mov dx,p8255+1 ;点亮led
out dx,al
mov ah,00000001b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
PUSH CX
MOV CX,00f00h ;延时
delay1: LOOP delay1
POP CX
mov ah,00000000b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
mov dl,sec2 ;秒十位 mov dh,0
mov si,dx
mov al,[bx][si]
mov dx,p8255+1 ;点亮led out dx,al
mov ah,00000010b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
PUSH CX
MOV CX,00f00h ;延时
delay2: LOOP delay2
POP CX
mov ah,00000000b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
mov dl,min1 ;分个位 mov dh,0
mov si,dx
mov al,[bx][si]
mov dx,p8255+1 ;点亮led out dx,al
mov ah,00000100b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
PUSH CX
MOV CX,00f00h ;延时
delay3: LOOP delay3
POP CX
mov ah,00000000b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
mov dl,min2 ;分十位 mov dh,0
mov si,dx
mov al,[bx][si]
mov dx,p8255+1 ;点亮led out dx,al
mov ah,00001000b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
PUSH CX
MOV CX,00f00h ;延时
delay4: LOOP delay4
POP CX
mov ah,00000000b mov al,ah
mov dx,p8255+2 ;pc输出选通信号 out dx,al
jmp play
mov ah,4ch
int 21h
INT_0A proc near ;中断服务子程序
cmp sec1,9
jz int1
inc sec1
jmp exit
int1: mov sec1,0
inc sec2
cmp sec2,6
jnz exit mov sec2,0 inc min1 cmp min1,10 jnz exit mov min1,0 inc min2 cmp min2,6 jnz exit mov min2,0 exit: mov al,20h out 20h,al iret
INT_0A endp
code ends end start
8251的发送代码:
data segment
io8254a equ 280h
io8251a equ 2b8h
io8251b equ 2b9h
mes1 db 'you can play a key on the keybord!',0dh,0ah,24h
mes2 dd mes1
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov dx,io8254a+3 ;设置8254计数器0工作方式
mov al,00010110b ;低字节,8位,方式3,二进制 out dx,al
mov dx,io8254a
mov al,52 ;给8254计数器0送初值(波特率1200,因子16,计数初值52)
out dx,al
mov dx,io8251b ;初始化8251
xor al,al
delay:
call out1
loop delay
mov al,40h ;向8251控制端口送40H,使其复位 call out1
mov al,7eh ;设置为1个停止位,8个数据位,波特率因子为16 call out1
mov al,27h ;向8251送控制字允许其发送和接收 call out1
waiti: mov dx,io8251b
in al,dx
test al,01 ;发送是否准备好
jz waiti
mov dx,io8251a
mov al,'I'
out dx,al ;发送
nop
mov cx,40h s51:
next:
exit:
out1
gg: loop gg
out1 endp
code ends
end start
loop s51 ;延时 mov dx,io8251b in al,dx test al,02 ;检查接收是否准备好 jz next ;没有,等待 mov dx,io8251a in al,dx ;准备好,接收 mov dl,al mov ah,02 ;将接收到的字符显示在屏幕上 int 21h jmp waiti mov ah,4ch ;退出 int 21h proc near ;向外发送一字节的子程序 out dx,al push cx mov cx,40h ;延时 pop cx ret
8250的发送代码
; TRANSLATE FILES
stack segment para stack'stack'
db 256 dup(0)
stack ends
data segment
name0 db 64h
db 64h dup(?)
buff dw 64h dup(?)
data ends
code segment para public 'code'
start proc far
assume cs: code,ds:data,es:data
push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
;*********************************************************** mov dx,3fbh ;3fb ctrl register
mov al,80h ;
out dx,al
mov dx,3f8h
mov al,60h
out dx,al
mov dx,3f9h ;高位00低位60确定频率是1200达成匹配 mov al,00
out dx,al
mov dx,3fbh
mov al,00011011b
out dx,al
inc dx
mov al,00001111b
out dx,al
;*********************************************************** shoufa: mov dx,3fdh ;读高位寄存器,判断是否接收好 in al,dx
test al,01h
jz shoufa
recv:mov dx,3f8h ;读数据
in al,dx
push bx
mov bx,0
mov ah,14 ;显示
int 10h
pop bx
;*********************************************************** fa: mov dx,3fdh ;线路状态寄存器
in al,dx
test al,20h ;判断是否显示好
jz fa
;*********************************************************** tr:
mov al,'2'
mov dx,3f8h
out dx,al
push bx
mov bx,0
mov ah,14 ;将发送的2显示
int 10h
pop bx
push cx
mov cx,0fh
gg:
nop
nop
nop
loop gg ;循环延迟
pop cx
jmp shoufa
start endp
code ends
end start
?
0809的代码
DATA SEGMENT
INT0B DW 2 DUP(?)
IMR DB ?
P_AD DW 280H
TAB DB '0123456789ABCDEF'
DATA ENDS
S SEGMENT STACK 'STACK'
DB 128 DUP(?)
S ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:S MAIN PROC PAR
MOV AX,DATA
MOV DS,AX
CLI
;修改中断向量表
PUSH ES
PUSH BX
MOV AH,35H ;保护原中断向量 MOV AL,0BH
INT 21H
MOV INT0B,ES
MOV INT0B+2,BX
POP BX
POP ES
PUSH DS
PUSH DX
MOV DX,OFFSET DISP ;设置新的中断向量 PUSH BX
MOV BX,SEG DISP
MOV DS,BX
POP BX
MOV AX,250BH
INT 21H
POP DX
POP DS
;8259清除0BH号中断屏蔽位
IN AL,21H
MOV IMR,AL
AND AL,0F7H
OUT 21H,AL
;启动AD转换
NEXT: MOV DX,P_AD MOV AL,0
OUT DX,AL
;等待中断,并检测是否有按键 PUSH CX
MOV CX,100
LOOP $
POP CX
STI
MOV AH,1
INT 16H
JZ NEXT
;恢复8259中断屏蔽位 CLI
MOV AL,IMR
OUT 21H,AL
;恢复中断向量表
PUSH DX
PUSH DS
MOV DX,INT0B MOV DS,DX
MOV DX,INT0B+2 MOV AX,250BH INT 21H
POP DS
POP DX
MOV AX,4C00H INT 21H
MAIN ENDP
DISP PROC FAR
PUSH AX
PUSH DX
MOV DX,P_AD ;读入AD转换结果 IN AL,DX
MOV AH,0 ;AH中为低位,AL中为高位 SHL AX,4
SHR AL,4
PUSH AX
MOV AL,AH
LEA BX,TAB
XLATB
MOV DL,AL
MOV AH,2
INT 21H
POP AX
LEA BX,TAB
XLATB
MOV DL,AL
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
MOV AL,20H
OUT 20H,AL
POP DX
POP AX
IRET
DISP ENDP
CODE ENDS
END MAIN
;输出高位 ;输出低位 ;输出回车 ;输出回车
0832的代码
DATA SEGMENT
ADD_DA DW 290H
LEN DB 32
DATA_IN DB 80h,96h,0aeh,0c5h,0d8h,0e9h,0f5h,0fdh db 0ffh,0fdh,0f5h,0e9h,0d8h,0c5h,0aeh,96h db 80h,66h,4eh,38h,25h,15h,09h,04h
db 00h,04h,09h,15h,25h,38h,4eh,66h
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
MAIN PROC FAR
MOV AX,DATA
MOV DS,AX
MOV DX,ADD_DA
BEGIN: MOV BH,LEN
LEA SI,DATA_IN
NEXT: MOV AL,[SI]
OUT DX,AL ;向DA送数据 INC SI
DEC BH
MOV CX,1 ;延时
LOOP $
CMP BH,0 ;一个周期已完成 JZ BEGIN
MOV AH,1 ;检测按键 INT 16H
JZ NEXT
MOV AH,4CH
INT 21H
MAIN ENDP
CODE ENDS
END MAIN