Skip to content

[微机实验/TD-PITE] 微机接口综合实验

Published: at 16:21

ToC

实验内容

实现一个以秒为单位的计时器。

使用 1MHz 的时钟源和 82548259 构成周期为 1 秒的计时中断时钟。

通过键盘 0-9 输入计时的分钟数A 控制计时过程的开始和结束,B 控制暂停和继续,C 退出程序。

具体功能如下:

实验接线

正常连接 82548255 即可。在本实现中,8254IOY08255IOY1

代码

不想动了,就这样吧,代码就不解释了(逃

A8255 EQU 0640H
B8255 EQU 0642H
C8255 EQU 0644H
CON8255 EQU 0646H
C008254 EQU 0600H
C018254 EQU 0602H
C028254 EQU 0604H
CON8254 EQU 0606H
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
CNT_STARTED DB 00H
CNT_PAUSED DB 00H
VAL_MIN:
DB 2 DUP(10H)
VAL_SEC:
DB 2 DUP(0)
MIR_COUNTER DB 00H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START PROC
MOV AX, 0
MOV DS, AX
;; INIT 8255
MOV AL, 81H ;;10001001B ;; A B OUT, C IN
MOV DX, CON8255
OUT DX, AL
;; MIR6
MOV AX, OFFSET MIR6
MOV SI, 38H
MOV [SI], AX
MOV AX, CS
MOV SI, 3AH
MOV [SI], AX
;; --------------------------------------------------
;; INIT 8259
CLI
MOV AL, 11H
OUT 20H, AL
MOV AL, 08H
OUT 21H, AL
MOV AL, 04H
OUT 21H, AL
MOV AL, 07H
OUT 21H, AL
MOV AL, 2FH
OUT 21H, AL
STI
;; --------------------------------------------------
;; --------------------------------------------------
;; INIT 8254
MOV AL, 00110110B
MOV DX, CON8254
OUT DX, AL
MOV DX, C008254
MOV AL, 24H ;; LOWER 8 BYTES
OUT DX, AL
MOV AL, 0F4H ;; HIGHER 8 BYTES
OUT DX, AL
;; --------------------------------------------------
MOV AX, DATA
MOV DS, AX
LO:
CALL NUM_DISPLAY
CALL SCAN
CMP AX, 10H
JE LO
CMP AX, 0AH ;; PRESS A TO START/STOP
JNE LO_NB
;;;;;;
CMP CNT_STARTED, 00H
JE COUNTER_START
;; COUNTER_STOP
MOV CNT_STARTED, 0
CALL CLR_TIME
LEA BX, VAL_MIN
MOV [BX], 1010H
JMP WAIT_UP
COUNTER_START:
MOV CNT_STARTED, 1
MOV CNT_PAUSED, 0
JMP WAIT_UP
;;;;;;
LO_NB:
CMP AX, 0BH ;; PRESS B TO PAUSE/RESUME
JNE LO_NC
XOR CNT_PAUSED, 1
JMP WAIT_UP
LO_NC:
CMP AX, 0CH ;; PRESS C TO EXIT
JE MA_EXIT
CMP AX, 0AH
JGE WAIT_UP
CALL MIN_SET
WAIT_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 21H
START ENDP
MIN_SET PROC
CMP CNT_STARTED, 1
JE MS_EXIT
LEA BX, VAL_MIN
MOV AH, [BX]
CMP AH, 10H
JE MS_SW
MOV AH, [BX+1]
CMP AH, 10H
JE MS_GW
JMP MS_EXIT
MS_SW:
MOV [BX], AL
JMP MS_EXIT
MS_GW:
MOV [BX+1], AL
MS_EXIT:
RET
MIN_SET ENDP
TIMER_RESET PROC
MOV CNT_STARTED, 0
CALL CLR_TIME
MOV CX, 3
TR_LO:
PUSH CX
CALL ZERO_BLINK
CALL DELAY
CALL NUM_DISPLAY_CLS
CALL DELAY_LONG
POP CX
LOOP TR_LO
CALL CLR_TIME
RET
TIMER_RESET ENDP
CLR_TIME PROC
LEA BX, VAL_MIN
MOV AH, 10H
MOV [BX], AH
MOV [BX+1], AH
LEA BX, VAL_SEC
MOV AH, 00H
MOV [BX], AH
MOV [BX+1], AH
RET
CLR_TIME ENDP
ZERO_BLINK PROC
PUSH CX
MOV CX, 0FFH
ZB:
PUSH CX
MOV AX, 0005H
CALL PUT
CALL DELAY
MOV AX, 0004H
CALL PUT
CALL DELAY
MOV AX, 0003H
CALL PUT
CALL DELAY
MOV AX, 0002H
CALL PUT
CALL DELAY
POP CX
LOOP ZB
POP CX
RET
ZERO_BLINK ENDP
NUM_DISPLAY PROC
CMP CNT_STARTED, 1
JE ND_TIMER
;; INPUT MODE
LEA BX, VAL_MIN
MOV SI, 0
MOV AH, [BX+SI]
MOV AL, 03H
CALL PUT
CALL DELAY
LEA BX, VAL_MIN
MOV SI, 0
MOV AH, [BX+SI+1]
MOV AL, 02H
CALL PUT
CALL DELAY
RET
ND_TIMER:
;; TIMER MODE
LEA BX, VAL_MIN
MOV SI, 0
MOV AH, [BX+SI]
MOV AL, 05H
CALL PUT
CALL DELAY
LEA BX, VAL_MIN
MOV SI, 0
MOV AH, [BX+SI+1]
MOV AL, 04H
CALL PUT
CALL DELAY
LEA BX, VAL_SEC
MOV SI, 0
MOV AH, [BX+SI]
MOV AL, 03H
CALL PUT
CALL DELAY
LEA BX, VAL_SEC
MOV SI, 0
MOV AH, [BX+SI+1]
MOV AL, 02H
CALL PUT
CALL DELAY
RET
NUM_DISPLAY ENDP
NUM_DISPLAY_CLS PROC
MOV CX, 5
ND_CLS:
MOV AH, 10H
MOV AL, AL
CALL PUT
LOOP ND_CLS
RET
NUM_DISPLAY_CLS ENDP
;; DECREASE SECOND & MIN WHEN NECESSARY
DEC_SEC PROC
CMP CNT_STARTED, 0 ;; NOT STARTED
JE DEC_EXIT
CMP CNT_PAUSED, 1 ;; PAUSED
JE DEC_EXIT
LEA BX, VAL_SEC
MOV AH, [BX+1]
CMP AH, 0
JE DS_JW_S
DEC AH
MOV [BX+1], AH
JMP DEC_EXIT
DS_JW_S:
MOV AH, 9
MOV [BX+1], AH
MOV AH, [BX]
CMP AH, 0
JE DS_JW_MG
DEC AH
MOV [BX], AH
JMP DEC_EXIT
DS_JW_MG:
MOV AH, 5
MOV [BX], AH
LEA BX, VAL_MIN
MOV AH, [BX+1]
CMP AH, 0
JE DS_JW_MS
DEC AH
MOV [BX+1], AH
JMP DEC_EXIT
DS_JW_MS:
MOV AH, 9
MOV [BX+1], AH
MOV AH, [BX]
CMP AH, 0
JE DS_FIN
DEC AH
MOV [BX], AH
JMP DEC_EXIT
DS_FIN:
CALL TIMER_RESET
DEC_EXIT:
RET
DEC_SEC ENDP
MIR6 PROC
STI
INC MIR_COUNTER
CMP MIR_COUNTER, 10H
JNE MIR6_FIN
MOV MIR_COUNTER, 0
CALL DEC_SEC
MIR6_FIN:
IRET
MIR6 ENDP
SCAN PROC
BEGIN:
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, 0
COLUMN:
MOV AL, CH
MOV DX, A8255
OUT DX, AL
MOV DX, C8255
IN AL, DX
L1:
TEST AL, 1
JNZ L2
MOV AL, 00H
JMP KCODE
L2:
TEST AL, 2
JNZ L3
MOV AL, 04H
JMP KCODE
L3:
TEST AL, 4
JNZ L4
MOV AL, 08H
JMP KCODE
L4:
TEST AL, 8
JNZ NEXT
MOV AL, 0CH
KCODE:
ADD AL, CL
JMP SCAN_FIN
NEXT:
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, 10H
SCAN_FIN:
RET
SCAN ENDP
;; RETURN WHETHER KEY PRESSED IN AX
KEY_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
RET
KP_NONE:
MOV AX, 0
RET
KEY_PRESSED ENDP
;; NUM: AH
;; POS: AL
PUT 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
RET
PUT ENDP
DELAY PROC
MOV CX, 0FFH
LOOP $
RET
DELAY ENDP
DELAY_LONG PROC
MOV CX, 0FFFFH
LOOP $
RET
DELAY_LONG ENDP
CODE ENDS
END START

效果


Previous Post
[微机实验/TD-PITE] 键盘扫描及数码管显示实验
Next Post
《恋爱绮谭 不存在的夏天》通关感想