0%

接口实验

第六章

6.1 I/O接口

I/O 接口就是 CPU 和外设之间的中间电路。

CPU 速度快,外设速度慢;CPU 用数字电平和总线工作,而外设可能是按键、LED、打印机、键盘、数码管等。两者不能直接简单相连,所以需要接口电路完成缓冲、状态检测、地址译码、读写控制等功能。I/O 接口要解决速度不匹配、电平不一致、信息格式转换、时序同步、地址译码、读写控制和中断控制等问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
主要功能:
1. 数据缓冲
2. 电平转换
3. 信息格式转换
4. 时序控制
5. 地址译码
6. 读/写控制
7. 中断控制

开关状态不能直接“变成 AL 里的数据”
LED 也不能直接被 MOV 指令点亮

开关 → 8255A A口 → CPU
CPU → 8255A B口 → LED

CPU 和外设通信时,实际访问的是 端口 Port

端口 作用
数据端口 存放输入/输出数据
状态端口 反映外设当前状态
控制端口/命令端口 接收 CPU 发出的控制命令

I/O 端口寻址方式

  1. 存储器映象寻址

    1
    2
    3
    ;I/O 端口和存储器统一编址
    ;可以用普通访存指令访问 I/O
    MOV AL, [端口地址]
  2. I/O 单独编址

    1
    2
    3
    4
    ;在 8086 系统中都采用 I/O 单独编址方式,用专门的 IN 和 OUT 指令访问 I/O 端口

    IN AL, DX
    OUT DX, AL

CPU 与外设的数据传送方式

  1. 程序控制方式:程序控制方式就是 CPU 用程序主动控制数据传送。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    ;无条件传送
    ;读开关状态
    ;控制 LED 亮灭

    IN AL, 60H
    OUT 61H, AL

    ;从端口 60H 读开关状态
    ;输出到端口 61H 控制 LED

    ;查询式传送
    ;先读状态口
    ;如果未准备好,继续等待
    ;如果准备好,再读/写数据口

    READ_STATUS:
    IN AL, PORT_STATUS
    TEST AL, 01H
    JZ READ_STATUS

    IN AL, PORT_DATA
    ;反复检测 READY 位
    ;READY = 1 时,才读取数据
  2. 中断方式:外设没准备好时,CPU 去做别的事外设准备好后,主动向CPU 发中断请求,CPU 响应中断后再处理数据

  3. DMA 方式:DMA 方式可在不受 CPU 干预的情况下,实现存储器与外设之间高速交换数据,典型 DMA 控制器是 8237A

6.2 8255A

8255A 内部包括:

1
2
3
4
5
6
7
8
A口 	8位
B口 8位
C口 8位
A组控制逻辑
B组控制逻辑
数据总线缓冲器
读/写控制逻辑
控制字寄存器

端口

1
2
3
4
5
6
7
8
数据总线A1A2接8255A的A0和A1选择端口,
00:A口
01:B口
10:C口
11:控制口

确认基地址之后,常见一位从低到高排列
如果用十六位接,低8位用偶地址访问,高地址用奇地址访问

8255A 控制字有两类:

1
2
1. 方式选择控制字
2. C口置位/复位控制字

方式选择控制字

特点:

1
D7 = 1

格式:

1
2
D7  D6 D5  D4  D3  D2  D1  D0
1 A组方式 A口 C高 B组 B口 C低

记忆重点:

1
2
3
1 = 输入
0 = 输出
D7 = 1 表示方式选择控制字

C口置位/复位控制字

特点:

1
D7 = 0

作用:

1
单独把 PC0~PC7 某一位设置为 1 或 0

例如课件中给了 PC5 输出正脉冲的程序:

1
2
3
4
5
MOV AL, 00001011B
OUT 63H, AL ; 置 PC5 为高电平

MOV AL, 00001010B
OUT 63H, AL ; 置 PC5 为低电平

也就是说,C口某一位可以单独控制。

8255A的工作方式

方式0:基本输入输出,把AB方式均设为0,D7=1,其余组合

方式1:AB口的工作需要联络信号来源C口,PC20和PC53

方式2:双向总线方式,A口既能用作输入口,也可以编程作为输出口

6.2.1 开关控制LED

有 8 个开关 K7~K0,8 个 LED LED7~LED0

要求:

1
2
开关断开 → 对应 LED 点亮
开关闭合 → 对应 LED 熄灭

硬件连接:

1
2
PA7~PA0 接 8 个开关
PB7~PB0 接 8 个 LED

端口地址:

1
2
3
4
F0H → A口
F2H → B口
F4H → C口
F6H → 控制口

分析

A口接开关,设为输入

B口接LED,设为输出

C口不工作

工作方式简单,不需要握手,所以使用方式0

控制字:

1
2
3
4
5
6
7
8
9
D7 = 1
D6D5 = 00 A口方式0
D4 = 1 A口输入
D3 = 0 C高输出
D2 = 0 B口方式0
D1 = 0 B口输出
D0 = 0 C低输出

10010000B = 90H

程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ASSUME CS:CODE

CODE SEGMENT
START:
MOV DX, 0F6H
MOV AL, 10010000B
OUT DX, AL

AGAIN:
MOV DX, 0F0H
IN AL, DX

MOV DX, 0F2H
OUT DX, AL

JMP AGAIN
CODE ENDS
END START

6.2.2

读 4 个开关,用七段 LED 显示 0F,4 个开关 `K3K0` 表示一个 4 位二进制数。

依旧简单输入输出使用方式0

控制字90H

60H A口 、61H B口、 62H C口、 63H 控制字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
DATA SEGMENT
TABLE DB 40H,79H,24H,30H,19H,12H,02H,78H
DB 00H,18H,80H,03H,43H,21H,06H,0EH
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE ,DA:DATA

MOV AX, DATA
MOV DS, AX

MOV AL, 90H
OUT 63H, AL

IN_PA:
IN AL, 60H
AND AL, 0FH

MOV BX, OFFSET TABLE
XLAT;AL = [BX + AL]

OUT 61H, AL

6.2.3 查询式输入

某输入设备通过接口向 CPU 传数据。CPU 必须先判断数据是否准备好,准备好后才能读取。

假设:

1
2
3
4
5
状态口:PORT_S
数据口:PORT_D
READY 位:D0
D0 = 0:数据未准备好
D0 = 1:数据准备好
1
2
3
4
5
6
WAIT_READY:
IN AL, PORT_S
TEST AL, 01H
JZ WAIT_READY

IN AL, PORT_D

6.2.4 查询式输出

CPU 要向外设输出数据,但外设可能正忙。必须等外设不忙时才能输出。

假设:

1
2
3
4
5
状态口:PORT_S
数据口:PORT_OUT
BUSY 位:D1
BUSY = 1:外设忙,不能输出
BUSY = 0:外设空闲,可以输出
1
2
3
4
5
6
7
WAIT_NOT_BUSY:
IN AL, PORT_S
TEST AL, 02H
JNZ WAIT_NOT_BUSY

MOV AL, DATA
OUT PORT_OUT, AL

6.2.5 4×4 矩阵键盘扫描

用 8255A 连接一个 4 行 × 4 列键盘,检测哪个键被按下。

课件中的键盘接口部分讲到:键盘中的开关排列成行、列矩阵,检测按键时要先判断是否有键按下,还要进行消抖处理。

按键只是“接通两根线”,不是“给两根线赋值”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1. 先让所有行输出 0
2. 读取列线
3. 如果列线全为 1,说明没有键按下
4. 如果某列为 0,说明有键按下
5. 延时 20ms 消抖
6. 逐行输出 0,其他行为 1
7. 再读列线,确定是哪一行哪一列
8. 得到键值

8255A A口:PA3~PA0 接 4 根行线,作为输出
8255A B口:PB3~PB0 接 4 根列线,作为输入
键未按下时:列线为 1
键按下时:如果对应行输出 0,则对应列读到 0

A口:60H
B口:61H
C口:62H
控制口:63H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
SCAN:
MOV AL, 00H
OUT PORT_A, AL ;行全设为0

IN AL, PORT_B ;取B(列)状态
AND AL, 0FH
CMP AL, 0FH
JE SCAN

CALL DELAY_20MS

;再次确认
MOV AL, 00H
OUT PORT_A, AL

IN AL, PORT_B
AND AL, 0FH
CMP AL, 0FH
JE SCAN

; 扫描第0行
MOV AL, 0FEH
OUT PORT_A, AL
IN AL, PORT_B
AND AL, 0FH
CMP AL, 0FH
JNE ROW0_FOUND

; 扫描第1行
MOV AL, 0FDH
OUT PORT_A, AL
IN AL, PORT_B
AND AL, 0FH
CMP AL, 0FH
JNE ROW1_FOUND

; 扫描第2行
MOV AL, 0FBH
OUT PORT_A, AL
IN AL, PORT_B
AND AL, 0FH
CMP AL, 0FH
JNE ROW2_FOUND

; 扫描第3行
MOV AL, 0F7H
OUT PORT_A, AL
IN AL, PORT_B
AND AL, 0FH
CMP AL, 0FH
JNE ROW3_FOUND

JMP SCAN
-------------到底咯QAQ嘎嘎-------------