实验内容:
1.8253定时实验,利用8253完成1秒的延时。
2.利用8253硬件延时控制跑马灯运行。
3.8255键盘显示实验
1.8253定时实验,利用8253完成1秒的延时
CODE SEGMENT
ASSUME CS:CODE
START: MOV AL,00110101B;8253初始化,选择通道0,采用BCD计数方式
MOV DX,2BBH
OUT DX,AL
MOV AL,00H;计数器初值均为2000,周期为2s,先写低字节,后写高字节
MOV DX,2B8H
OUT DX,AL
MOV AL,20H
OUT DX,AL
MOV AL,01110111B;8253初始化,选择通道1,采用BCD计数方式
MOV DX,2BBH
OUT DX,AL
MOV AL,00H;计数器初值均为2000,周期为2s,先写低字节,后写高字节
MOV DX,2B9H
OUT DX,AL
MOV AL,20H
OUT DX,AL
CODE ENDS
END START
2.利用8253硬件延时控制跑马灯运行
CODE SEGMENT
ASSUME CS:CODE
MOV AL,10010010H;8255初始化
MOV DX,283H
OUT DX,AL
;8253硬件延时1s程序
START: MOV AL,00110101B;8253初始化,选择通道0,采用BCD计数方式
MOV DX,2BBH
OUT DX,AL
MOV AL,00H;计数器初值均为2000,周期为2s,先写低字节,后写高字节
MOV DX,2B8H
OUT DX,AL
MOV AL,20H
OUT DX,AL
MOV AL,01110111B;8253初始化,选择通道1,采用BCD计数方式
MOV DX,2BBH
OUT DX,AL
MOV AL,00H;计数器初值均为2000,周期为2s,先写低字节,后写高字节
MOV DX,2B9H
OUT DX,AL
MOV AL,20H
OUT DX,AL
;8255输出程序
MOV AL,01H
MOV BL,AL;将Al值送到BL暂存
;8253输出电平上升沿进入
XUN1: MOV DX,281H;从8255B口输入
IN AL,DX
TEST AL,01H;测试8253是否为高电平
JNZ XUN1;否,继续循环测试
XUN2: MOV DX,280H;从8255A口输入
IN AL,DX
TEST AL,01H;测试开关输出是否为高电平
JNZ XUN2;否,继续循环测试
;8255输出
MOV AL,BL;将暂存在BL中的值送到AL中
MOV DX,282H
OUT DX,AL;C口输出
;8253输出电平下降沿退出
XUN3: MOV DX,281H;从8255B口输入
IN AL,DX
TEST AL,01H;测试8253是否为高电平
JZ XUN3;是,继续循环测试
;左移一位,暂存在BL中,防止AL被修改
ROL BL,1
JMP XUN1;循环检测该程序
CODE ENDS
END START
3.8255键盘显示实验
PORT_A EQU 280H;A口地址
PORT_B EQU 281H;B口地址
PORT_C EQU 282H ;C口地址
PORT_CTL EQU 283H;控制字寄存器地址
DATA SEGMENT
;键盘扫描码表
TABLE DB 77H,7bH,7DH,7EH,0B7H,0BBH,0BDH,0BEH
DB 0D7H,0DBH,0DDH,0DEH,0E7H,0EBH,0EDH,0EEH
;0~F的七段代码编码
TABLE1 DB 0BFH,86H,0dbH,0CFH,0E6H,0EdH,0FDH,87H
DB 0FFH,0E7H,0F7H,0FCH,0B9H, 0DEH,0F9H,0F1H
DATA ENDS
;堆栈段
STACK SEGMENT STACK
DW 50 DUP(0)
TOP_STACK LABEL WORD
STACK ENDS
;代码段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA;SS:STACK
START: MOV AX,STACK
MOV SS,AX
LEA SP,TOP_STACK
MOV AX,DATA
MOV DS,AX
MOV DX,PORT_CTL
MOV AL,10000010B;8255初始化,A口输出,B口和C口输入,方式0
OUT DX,AL
;向所有行送0
S: MOV DX,PORT_A
MOV AL,0
OUT DX,AL
;读列,查看所有键是否松开
MOV DX,PORT_B
WAIT_OPEN: IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE WAIT_OPEN
;各键均已松开,查列是否有键按下
WAIT_PRES: IN AL,DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES
;再查列,看键是否仍被压着
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES
;键仍被压着,确定哪一个键被压下
MOV AL,0FEH
MOV CL,AL
NEXT_ROW: MOV DX,PORT_A
OUT DX,AL
MOV DX,PORT_B
IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE ENCODE;列值不全为1,表示有键按下,转去编码
ROL CL,01
MOV AL,CL
JMP NEXT_ROW
;已找到某一列为0,对压键的行列值编码
ENCODE: MOV BX,000FH
IN AL,DX
NEXT_TRY: CMP AL,TABLE[BX];比较读出的行列值和表中是否一致
JE DONE
DEC BX
JNS NEXT_TRY
MOV AH,01
JMP EXIT
DONE: MOV DX,PORT_C;C口输出
MOV AL,TABLE1[BX];查0~F的七段代码编码
OUT DX,AL
JMP S ;循环检测该程序
EXIT: HLT
CODE ENDS
END START