⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyscan.asm

📁 A1.asm 显示程序实验 STACK1 SEGMENT STACK DW 256 DUP(?) STACK1 ENDS DATA SEGMENT USE16 MES1 DB
💻 ASM
字号:
;Keyscan.asm
;键盘扫描及数码管显示实验

;****************根据查看端口资源修改下列符号值*******************
IOY0         EQU   9C00H           ;片选IOY0对应的端口始地址
;*****************************************************************
MY8255_A     EQU   IOY0+00H*4      ;8255的A口地址
MY8255_B     EQU   IOY0+01H*4      ;8255的B口地址
MY8255_C     EQU   IOY0+02H*4      ;8255的C口地址
MY8255_MODE  EQU   IOY0+03H*4      ;8255的控制寄存器地址

STACK1 SEGMENT STACK
        DW 256 DUP(?)
STACK1 ENDS

DATA   SEGMENT
DTABLE DB   3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
DATA   ENDS                       ;键值表,0~F对应的7段数码管的段位值

CODE   SEGMENT
      	ASSUME CS:CODE,DS:DATA

START: MOV  AX,DATA
	   MOV  DS,AX

 	   MOV  SI,3000H               ;建立缓冲区,存放要显示的键值
	   MOV  AL,00H                 ;先初始化键值为0
	   MOV  [SI],AL
	   MOV  [SI+1],AL
	   MOV  [SI+2],AL
	   MOV  [SI+3],AL
	   MOV  [SI+4],AL
	   MOV  [SI+5],AL
	   MOV  DI,3005H

       MOV  DX,MY8255_MODE         ;初始化8255工作方式 
       MOV  AL,81H                 ;方式0,A口、B口输出,C口低4位输入  
	   OUT  DX,AL 

BEGIN: CALL DIS                    ;显示刷新                     
	   CALL CLEAR                  ;清屏
	   CALL CCSCAN                 ;扫描按键
	   JNZ  GETKEY1                ;有键按下则跳置GETKEY1  

       MOV  AH,1                   ;判断PC键盘是否有按键按下
       INT  16H
       JZ   BEGIN                  ;无按键则跳回继续循环,有则退出
QUIT:  MOV  AX,4C00H               ;返回到DOS
       INT  21H

GETKEY1:CALL DIS                   ;显示刷新
       CALL DALLY                    
       CALL DALLY
       CALL CLEAR                  ;清屏
	   CALL CCSCAN                 ;再次扫描按键
	   JNZ  GETKEY2                ;有键按下则跳置GETKEY2
	   JMP  BEGIN                  ;否则跳回开始继续循环

GETKEY2:MOV CH,0FEH
	   MOV  CL,00H                 ;设置当前检测的是第几列
COLUM: MOV  AL,CH                  ;选取一列,将X1~X4中一个置0            
       MOV  DX,MY8255_A 
	   OUT  DX,AL
       MOV  DX,MY8255_C            ;读Y1~Y4,用于判断是哪一行按键闭合 
	   IN   AL,DX

L1:    TEST AL,01H                 ;是否为第1行
       JNZ  L2                     ;不是则继续判断  
       MOV  AL,00H                 ;设置第1行第1列的对应的键值
	   JMP  KCODE

L2:    TEST AL,02H                 ;是否为第2行
       JNZ  L3                     ;不是则继续判断
       MOV  AL,04H                 ;设置第2行第1列的对应的键值
       JMP  KCODE

L3:    TEST AL,04H                 ;是否为第3行
       JNZ  L4                     ;不是则继续判断
       MOV  AL,08H                 ;设置第3行第1列的对应的键值
	   JMP  KCODE 

L4:    TEST AL,08H                 ;是否为第4行
       JNZ  NEXT                   ;不是则继续判断
       MOV  AL,0CH                 ;设置第4行第1列的对应的键值

KCODE: ADD  AL,CL                  ;将第1列的值加上当前列数,确定按键值
	   CALL PUTBUF                 ;保存按键值

	   PUSH AX
KON:   CALL DIS                    ;显示刷新
	   CALL CLEAR                  ;清屏
	   CALL CCSCAN                 ;扫描按键,判断按键是否弹起
	   JNZ  KON                    ;未弹起则继续循环等待弹起
	   POP  AX

NEXT:  INC  CL                     ;当前检测的列数递增                    
	   MOV  AL,CH
	   TEST AL,08H                 ;检测是否扫描到第4列
	   JZ   KERR                    ;是则跳回到开始处
	
       ROL  AL,1                   ;没检测到第4列则准备检测下一列
	   MOV  CH,AL
	   JMP  COLUM
KERR:  JMP  BEGIN


CCSCAN PROC NEAR                   ;扫描是否有按键闭合子程序
       MOV  AL,00H                              
       MOV  DX,MY8255_A            ;将4列全选通,X1~X4置0
	   OUT  DX,AL
       MOV  DX,MY8255_C 
       IN   AL,DX                  ;读Y1~Y4
	   NOT  AL
       AND  AL,0FH                 ;取出Y1~Y4的反值
	   RET
CCSCAN ENDP

CLEAR PROC NEAR                    ;清除数码管显示子程序
       MOV  DX,MY8255_B            ;段位置0即可清除数码管显示   
       MOV  AL,00H
       OUT  DX,AL
	   RET
CLEAR ENDP

DIS PROC NEAR                      ;显示键值子程序
       PUSH AX                     ;以缓冲区存放的键值为键值表偏移找到键值并显示
	   MOV  SI,3000H                              
	   MOV  DL,0DFH
	   MOV  AL,DL
AGAIN: PUSH DX
       MOV  DX,MY8255_A 
       OUT  DX,AL                  ;设置X1~X4,选通一个数码管    
       MOV  AL,[SI]                ;取出缓冲区中存放键值                  
       MOV  BX,OFFSET DTABLE
	   AND  AX,00FFH
	   ADD  BX,AX                  
	   MOV  AL,[BX]                ;将键值作为偏移和键值基地址相加得到相应的键值 
       MOV  DX,MY8255_B 
	   OUT  DX,AL                  ;写入数码管A~Dp
	   CALL DALLY
	   INC  SI                     ;取下一个键值
       POP  DX
       MOV  AL,DL
	   TEST AL,01H                 ;判断是否显示完?
       JZ   OUT1                   ;显示完,返回
	   ROR  AL,1             
	   MOV  DL,AL
	   JMP  AGAIN                  ;未显示完,跳回继续
OUT1:  POP  AX                     
	   RET
DIS ENDP

PUTBUF PROC NEAR                   ;保存键值子程序
       MOV  SI,DI
       MOV  [SI],AL
	   DEC  DI
	   CMP  DI,2FFFH
	   JNZ  GOBACK
	   MOV  DI,3005H
GOBACK: RET
PUTBUF ENDP

DALLY PROC NEAR                    ;软件延时子程序
       PUSH CX
       MOV  CX,00FFH
D1:    MOV  AX,00FFH
D2:    DEC  AX
	   JNZ  D2
	   LOOP D1
	   POP  CX
	   RET
DALLY ENDP

CODE ENDS
      END START

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -