(o・∇・o)
(o・∇・o)
TD-PITE 型微机系统与接口实验

说明

本系列为 TD-PITE 型微机系统与接口实验的实验源码,附选做实验。

实验内容

  1. 8255 并行接口实验(略)
  2. 存储器扩展实验
  3. 8259 中断优先级实验
  4. A/D 转换实验
  5. D/A 转换实验
  6. 8254 定时/计数器实验
  7. 8251 串行接口实验
  8. 数码管显示实验
  9. 键盘扫描及数码管显示实验
  10. 微机接口综合实验

代码片段

这里列举一些可以复用的代码片段,可用于期末测试。

程序结构

;; 四个 IOY 口对应的首地址,供参考
IOY0 EQU 0600H
IOY1 EQU 0640H
IOY2 EQU 0680H
IOY3 EQU 06C0H

;; 栈区声明
SSEG SEGMENT STACK
  DW 20 DUP(?)
SSEG ENDS

;; 数据区声明
DATA SEGMENT
  DB 8 DUP(?)
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:SSEG

START PROC
  MOV AX, 0
  MOV DS, AX
  ;; --------------------------------------------------
  ;; 此时可初始化中断
  ;; MOV AX, 1
  ;; --------------------------------------------------

  MOV AX, DATA
  MOV DS, AX
  ;; --------------------------------------------------
  ;; 此时可使用 DATA 段
  ;; MOV AX, 1
  ;; --------------------------------------------------

  ;; 程序退出
  MOV AX, 4C00H
  INT 21H
START ENDP

;; --------------------------------------------------
;; 此处可放置其他函数
;; TEST PROC
;;   RET
;; TEST ENDP
;; --------------------------------------------------
CODE ENDS
END START

延时

可以通过调整 CX 的大小,控制延时的时间。

如果不考虑 CX,可以考虑删除下面关于 CXPUSHPOP

DELAY PROC
  PUSH CX
  MOV CX, 0FFH
  LOOP $
  POP CX
  RET
DELAY ENDP

8259 初始化(中断)

放置在可初始化中断处。如果不需要使用 MIR7,可以删除 ;;MIR7 部分。

;; MIR6
MOV AX, OFFSET MIR6
MOV SI, 38H
MOV [SI], AX
MOV AX, CS
MOV SI, 3AH
MOV [SI], AX

;; MIR7
MOV AX, OFFSET MIR7
MOV SI, 3CH
MOV [SI], AX
MOV AX, CS
MOV SI, 3EH
MOV [SI], AX

;; --------------------------------------------------
;; 初始化 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
;; --------------------------------------------------

8254 方波初始化(计数器)

通过改变计数初值,可以改变方波的周期。

当连接 18.432KHz 时钟源时,使用 4800H 作为计数初值可以使 OUT 的输出周期为 1s

MOV DX, CON8254
MOV AL, 00110110B
OUT DX, AL

MOV DX, C018254
MOV AL, 00H       ;; 低 8 位
OUT DX, AL

MOV AL, 48H       ;; 高 8 位
OUT DX, AL

数码管显示

预定义数据

;; 预定义 8255 的端口
;; 此处使用的是 IOY0,根据需求修改
A8255 EQU 0600H
B8255 EQU 0602H
C8255 EQU 0604H
CON8255 EQU 0606H

;; 在数据区中增加如下内容
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
DATA ENDS

初始化 8255

MOV AL, 81H
MOV DX, CON8255
OUT DX, AL

字符显示

AH 的数值输出到第 AL 位数码管。

;; 输出 AH 到 AL 位数码管
PUT PROC
  PUSH AX
  LEA BX, SEQ
  PUSH AX
  MOV AH, 0
  MOV SI, AX
  MOV DX, A8255
  MOV AL, [BX+SI]
  OUT DX, AL
  POP AX
  LEA BX, TBL
  MOV AL, AH
  MOV AH, 0
  MOV SI, AX
  MOV DX, B8255
  MOV AL, [BX+SI]
  OUT DX, AL
  POP AX
  RET
PUT ENDP

键盘输入

检测是否有键按下

调用后通过检查 AX 判断是否有键按下。AX=1 表示有键按下,AX=0 表示无键按下。

KEY_PRESSED PROC
  MOV DX, A8255
  MOV AL, 00H
  OUT DX, AL
  MOV DX, C8255
  IN AL, DX
  AND AL, 0FH
  CMP AL, 0FH
  JE KP_NONE
  MOV AX, 1
  RET
KP_NONE:
  MOV AX, 0
  RET
KEY_PRESSED ENDP

检测当前按下的按键

调用后 AX 中存储按下的键。当无键按下时,AX=10H

SCAN PROC
BEGIN:
  CALL KEY_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

简单使用流程

START PROC
  MOV AX, DATA
  MOV DS, AX

  MOV AL, 81H
  MOV DX, CON8255
  OUT DX, AL       ;; 初始化 8255

  MOV AX, 0000H
LO:
  CALL NUM_DISPLAY ;; 数码管显示
  CALL SCAN        ;; 扫描键盘输入
  CMP AX, 10H      ;; 检测是否有键按下
  JE LO            ;; 无键按下则继续循环
WAIT_UP:
  CALL NUM_DISPLAY ;; 可在此时在数码管上显示数据
  CALL KEY_PRESSED ;; 检测是否有键按下
  CMP AX, 1        ;; 如有键按下
  JE WAIT_UP       ;; 则继续等待,即等待 KEY_UP
  JMP LO           ;; 用户释放按键,继续监听下一个按键事件

  MOV AX, 4C00H
  INT 21H
START ENDP