第六章
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 2 3
| ;I/O 端口和存储器统一编址 ;可以用普通访存指令访问 I/O MOV AL, [端口地址]
|
I/O 单独编址
1 2 3 4
| ;在 8086 系统中都采用 I/O 单独编址方式,用专门的 IN 和 OUT 指令访问 I/O 端口
IN AL, DX OUT DX, AL
|
CPU 与外设的数据传送方式
程序控制方式:程序控制方式就是 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 时,才读取数据
|
中断方式:外设没准备好时,CPU 去做别的事外设准备好后,主动向CPU 发中断请求,CPU 响应中断后再处理数据
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 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
| 单独把 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
|