Skip to content

TD-PITE 型微机系统与接口实验

Published: at 16:30

ToC

说明

本系列为 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

Previous Post
Shinym@s 逆向系列