ToC
实验内容
在数码管上显示键盘输入的内容,新输入的内容显示在数码管的最右侧。
当数码管显示空间已满时,删除最左侧的文本。
实验接线
这次的接线和上次是一样的。唯一的不同是不能不连 Y1-Y4
了(笑)
代码
A8255 EQU 0600HB8255 EQU 0602HC8255 EQU 0604HCON8255 EQU 0606HROWOUT EQU 200H
SSEG SEGMENT STACK DW 20 DUP(?)SSEG ENDS
DATA SEGMENT TBL: DB 3FH ;; 0 DB 06H ;; 1 DB 5BH ;; 2 DB 4FH ;; 3 DB 66H ;; 4 DB 6DH ;; 5 DB 7DH ;; 6 DB 07H ;; 7 DB 7FH ;; 8 DB 6FH ;; 9 DB 77H ;; A DB 7CH ;; B DB 39H ;; C DB 5EH ;; D DB 79H ;; E DB 71H ;; F SEQ: DB 00011111B ;; POS 0 DB 00101111B ;; POS 1 DB 00110111B ;; POS 2 DB 00111011B ;; POS 3 DB 00111101B ;; POS 4 DB 00111110B ;; POS 5 VAL: DB 6 DUP(0) VAL_USED: DB 6 DUP(0) VAL_HEAD DW 0005HDATA ENDS
CODE SEGMENTASSUME CS:CODE, DS:DATA, SS:SSEGSTART PROC MOV AX, DATA MOV DS, AX
MOV AL, 81H ;;10001001B ;; A B OUT, C IN MOV DX, CON8255 OUT DX, AL
MOV AX, 0000HLO: CALL VAL_DISPLAY CALL SCAN CMP AX, 10H JE LO CALL VAL_INSERTWAIT_UP: CALL VAL_DISPLAY CALL KEY_PRESSED CMP AX, 1 JE WAIT_UP JMP LO
MOV AX, 4C00H INT 21HSTART ENDP
SCAN PROCBEGIN: CALL KEY_PRESSED ;; EXIT IF NOT PRESSED CMP AX, 0 JE SCAN_NO_KEY
CALL DELAY CALL KEY_PRESSED CMP AX, 0 JE SCAN_NO_KEY
MOV CH, 0FEH MOV CL, 0COLUMN: MOV AL, CH MOV DX, A8255 OUT DX, AL MOV DX, C8255 IN AL, DXL1: TEST AL, 1 JNZ L2 MOV AL, 00H JMP KCODEL2: TEST AL, 2 JNZ L3 MOV AL, 04H JMP KCODEL3: TEST AL, 4 JNZ L4 MOV AL, 08H JMP KCODEL4: TEST AL, 8 JNZ NEXT MOV AL, 0CHKCODE: ADD AL, CL JMP SCAN_FINNEXT: INC CL MOV AL, CH TEST AL, 08H JE SCAN_NO_KEY ROL AL, 1 MOV CH, AL JMP COLUMN
SCAN_NO_KEY: MOV AX, 10HSCAN_FIN: RETSCAN ENDP
;; RETURN WHETHER KEY PRESSED IN AXKEY_PRESSED PROC MOV DX, A8255 MOV AL, 00H OUT DX, AL ;; LINE OUTPUT 0000
MOV DX, C8255 IN AL, DX ;; GET LINE STATUS AND AL, 0FH CMP AL, 0FH JE KP_NONE
MOV AX, 1 ;; KEY PRESSED RETKP_NONE: MOV AX, 0 RETKEY_PRESSED ENDP
;; INSERT AX TO VAL[VAL_HEAD];;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INDEX: 0 1 2 3 4 5;; VALUE: A B C D E F;; HEAD: |;; INPUT: 0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INDEX: 0 1 2 3 4 5;; VALUE: 0 B C D E F;; HEAD: |;; (-> 1 BYTE);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;VAL_INSERT PROC PUSH BX LEA BX, VAL MOV SI, VAL_HEAD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; !!!CAUTION!!! ;; ;; MAKE SURE TO USE 8-BIT REGISTER ;; ;; IF YOU WANT TO MOVE BYTES ;; ;; BETWEEN MEMORY AND REGISTER!! ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV [BX+SI], AL ;; NUMBER BYTE MOV DL, 1 MOV [BX+SI+6], DL ;; DISPLAY BYTE INC SI CMP SI, 5 ;; HEAD <= 5, SKIP JLE VI_EXIT
SUB SI, 6 ;; MAKE HEAD IN [0, 5]
VI_EXIT: MOV VAL_HEAD, SI POP BX RETVAL_INSERT ENDP
;; DISPLAY VAL ARRAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INDEX: 0 1 2 3 4 5;; VALUE: A B C D E F;; HEAD: |;; THIS IS THE SAME DIRECTION AS SCREEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;VAL_DISPLAY PROC PUSH CX MOV CX, 6
LEA BX, VAL MOV SI, VAL_HEAD
VD_LO: PUSH CX MOV AH, [BX+SI] MOV AL, CL DEC AL
MOV DH, [BX+SI+6] CMP DH, 0 JE VD_SKIP_BIT
PUSH BX PUSH SI CALL PUT CALL DELAY POP SI POP BX
VD_SKIP_BIT: POP CX ;; CALCULATE NEXT SI INC SI CMP SI, 5 ;; HEAD <= 5, SKIP JLE VD_SI_SKIP SUB SI, 6
VD_SI_SKIP: LOOP VD_LO
POP CX RETVAL_DISPLAY ENDP
;; NUM: AH;; POS: ALPUT PROC PUSH AX
;; SELECT POS LEA BX, SEQ PUSH AX MOV AH, 0 MOV SI, AX
;; OUTPUT POS MOV DX, A8255 MOV AL, [BX+SI] OUT DX, AL POP AX
;; SELECT NUM LEA BX, TBL MOV AL, AH MOV AH, 0 MOV SI, AX
;; OUTPUT DATA MOV DX, B8255 MOV AL, [BX+SI] OUT DX, AL
POP AX RETPUT ENDP
DELAY PROC MOV CX, 0FFH LOOP $ RETDELAY ENDP
CODE ENDSEND START
选做实验
说明
通过键盘输入 0-E
,将刚刚输入的一位数字显示在数码管上。
最开始数码管无显示。在输入新数字后,将输入的数字显示在数码管最右端。之后每次输入数字,数字的显示位置向左移动一格。
当显示的数字已经位于最左时,此时输入的数字并不立即向右移动,而是先在最左停顿一次,下一个输入的数字再向右移动。
到达最右时的处理和最左一致。
键盘输入 F
时程序退出。
效果
上面说的这段话简直就不是人话,还是看一下实际的效果吧(
代码
A8255 EQU 0600HB8255 EQU 0602HC8255 EQU 0604HCON8255 EQU 0606HROWOUT EQU 200H
SSEG SEGMENT STACK DW 20 DUP(?)SSEG ENDS
DATA SEGMENT TBL: DB 3FH ;; 0 DB 06H ;; 1 DB 5BH ;; 2 DB 4FH ;; 3 DB 66H ;; 4 DB 6DH ;; 5 DB 7DH ;; 6 DB 07H ;; 7 DB 7FH ;; 8 DB 6FH ;; 9 DB 77H ;; A DB 7CH ;; B DB 39H ;; C DB 5EH ;; D DB 79H ;; E DB 71H ;; F DB 00H ;; CLR SEQ: DB 00011111B ;; POS 0 DB 00101111B ;; POS 1 DB 00110111B ;; POS 2 DB 00111011B ;; POS 3 DB 00111101B ;; POS 4 DB 00111110B ;; POS 5 VAL DB 00H VAL_POS DB 00H VAL_SHOW DB 00H VAL_STEP DB 00HDATA ENDS
CODE SEGMENTASSUME CS:CODE, DS:DATA, SS:SSEGSTART PROC MOV AX, DATA MOV DS, AX
MOV AL, 81H ;;10001001B ;; A B OUT, C IN MOV DX, CON8255 OUT DX, AL
MOV AX, 0000HLO: CALL NUM_DISPLAY CALL SCAN CMP AX, 10H JE LO CMP AX, 0FH JE MA_EXIT CALL NUM_SETWAIT_UP: CALL NUM_DISPLAY CALL KEY_PRESSED CMP AX, 1 JE WAIT_UP JMP LO
MA_EXIT: MOV AX, 1000H CALL PUT MOV AX, 4C00H INT 21HSTART ENDP
SCAN PROCBEGIN: CALL KEY_PRESSED ;; EXIT IF NOT PRESSED CMP AX, 0 JE SCAN_NO_KEY
CALL DELAY CALL KEY_PRESSED CMP AX, 0 JE SCAN_NO_KEY
MOV CH, 0FEH MOV CL, 0COLUMN: MOV AL, CH MOV DX, A8255 OUT DX, AL MOV DX, C8255 IN AL, DXL1: TEST AL, 1 JNZ L2 MOV AL, 00H JMP KCODEL2: TEST AL, 2 JNZ L3 MOV AL, 04H JMP KCODEL3: TEST AL, 4 JNZ L4 MOV AL, 08H JMP KCODEL4: TEST AL, 8 JNZ NEXT MOV AL, 0CHKCODE: ADD AL, CL JMP SCAN_FINNEXT: INC CL MOV AL, CH TEST AL, 08H JE SCAN_NO_KEY ROL AL, 1 MOV CH, AL JMP COLUMN
SCAN_NO_KEY: MOV AX, 10HSCAN_FIN: RETSCAN ENDP
;; RETURN WHETHER KEY PRESSED IN AXKEY_PRESSED PROC MOV DX, A8255 MOV AL, 00H OUT DX, AL ;; LINE OUTPUT 0000
MOV DX, C8255 IN AL, DX ;; GET LINE STATUS AND AL, 0FH CMP AL, 0FH JE KP_NONE
MOV AX, 1 ;; KEY PRESSED RETKP_NONE: MOV AX, 0 RETKEY_PRESSED ENDP
;; SET AL TO VAL & MOVE POSNUM_SET PROC PUSH AX MOV VAL, AL MOV AL, VAL_POS ADD AL, VAL_STEP
CMP VAL_STEP, 0 ;; REGULAR STATUS: STEP != 0 JNE NS_REG CMP VAL_POS, 5 JE NS_LMOST MOV VAL_STEP, 1 ;; POS == 0, RIGHT MOST JMP NS_FINNS_LMOST: ;; POS == 5, LEFT MOST MOV VAL_STEP, -1 JMP NS_FIN
NS_REG: CMP AL, 5 JE NS_SET0 CMP AL, 0 JE NS_SET0 JMP NS_FINNS_SET0: MOV VAL_STEP, 0NS_FIN: MOV VAL_SHOW, 1 MOV VAL_POS, AL POP AX RETNUM_SET ENDP
;; DISPLAY VAL AT VAL_POSNUM_DISPLAY PROC ;MOV AL, VAL_SHOW CMP VAL_SHOW, 0 JE ND_SKIP
MOV AH, VAL MOV AL, VAL_POS CALL PUT CALL DELAYND_SKIP: RETNUM_DISPLAY ENDP
;; NUM: AH;; POS: ALPUT PROC PUSH AX
;; SELECT POS LEA BX, SEQ PUSH AX MOV AH, 0 MOV SI, AX
;; OUTPUT POS MOV DX, A8255 MOV AL, [BX+SI] OUT DX, AL POP AX
;; SELECT NUM LEA BX, TBL MOV AL, AH MOV AH, 0 MOV SI, AX
;; OUTPUT DATA MOV DX, B8255 MOV AL, [BX+SI] OUT DX, AL
POP AX RETPUT ENDP
DELAY PROC MOV CX, 0FFH LOOP $ RETDELAY ENDP
CODE ENDSEND START