(o・∇・o)
(o・∇・o)
[微机实验/TD-PITE] 微机接口综合实验
[微机实验/TD-PITE] 微机接口综合实验

实验内容

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

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

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

具体功能如下:

  • 初始状态:无显示。此时通过 0-9 输入计时初值,范围为 1-99 分钟,显示在数码管 34 上。
  • A 键(启动/取消):初值设置完成后按 A 键,从计数初值开始倒计时。数码管 12 显示分,34 显示秒;计时过程中按 A 键,停止倒计时,回到初始状态。
  • B 键(暂停/继续):计时过程中按 B 键,暂停倒计时,显示停止时间;再次按 B 键,从停止时间继续倒计时。
  • 计时结束:倒计时至 0000 时,闪烁三次后回到初始状态。
  • C 键(退出):任何时刻按 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

效果

发表评论

textsms
account_circle
email

(o・∇・o)

[微机实验/TD-PITE] 微机接口综合实验
实验内容 实现一个以秒为单位的计时器。 使用 1MHz 的时钟源和 8254、8259 构成周期为 1 秒的计时中断时钟。 通过键盘 0-9 输入计时的分钟数,A 控制计时过程的开始和结束,B 控…
扫描二维码继续阅读
2020-11-16