Files
final-exam/接口与通讯技术/复习文档/8255A可编程并行接口.md
T

413 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags:
- 接口与通讯技术
- 8255A
- 并行接口
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8255A 可编程并行接口
## 概述
8255A(Programmable Peripheral Interface, PPI)是 Intel 公司生产的通用可编程并行 I/O 接口芯片,**在全部 4 套试卷中均有出现**,是本课程最高频考点。它通过软件配置 3 个 8 位端口(A/B/C)的工作方式,灵活适配多种外设需求。
> [!tip] 考试要点
> - **控制字计算**:方式控制字(D7=1)和 C 口按位控制字(D7=0)的区别
> - **工作方式对比**:方式 0/1/2 的特点、联络信号
> - **端口地址推算**:已知一个端口地址推算其余端口和控制口地址
## 正文
### 1. 内部结构
8255A 内部由 **4 个功能模块** 组成:
```mermaid
graph LR
CPUDB["CPU 数据总线"] --> DBB["数据总线缓冲器"]
DBB --> RWCL["读/写控制逻辑"]
RWCL --> AGC["A 组控制"]
RWCL --> BGC["B 组控制"]
AGC --> PA["端口 A\nPA0~PA7"]
AGC --> CH["端口 C 高 4 位\nPC4~PC7"]
BGC --> PB["端口 B\nPB0~PB7"]
BGC --> CL["端口 C 低 4 位\nPC0~PC3"]
```
| 模块 | 功能 |
|------|------|
| 数据总线缓冲器 | 三态 8 位缓冲器,实现 CPU 与 8255A 之间的数据传输 |
| 读/写控制逻辑 | 根据 CS、RD、WR、A1、A0 信号控制端口的读写操作 |
| A 组控制 | 控制端口 A 和端口 C 高 4 位的工作方式 |
| B 组控制 | 控制端口 B 和端口 C 低 4 位的工作方式 |
### 2. 三个端口的能力
| 端口 | 可用工作方式 | 说明 |
|:----:|:----------:|------|
| **端口 A** | 方式 0、方式 1、方式 2 | 功能最全,唯一支持双向传输(方式 2)的端口 |
| **端口 B** | 方式 0、方式 1 | 不支持方式 2 |
| **端口 C** | 仅方式 0 | 可分为高 4 位和低 4 位两组独立使用;在方式 1/2 下部分引脚被复用为联络信号 |
> [!question] 思考题
> 为什么只有端口 A 支持方式 2(双向传输)?这与 8255A 的硬件设计有什么关系?
>
> 提示:方式 2 需要同时占用输入和输出的联络信号线,这些信号来自端口 C——只有 A 组控制能支配足够多的 C 口引脚(5 根)来支持双向握手。
### 3. 三种工作方式对比速查
| 特性 | 方式 0(基本 I/O) | 方式 1(选通 I/O) | 方式 2(双向总线) |
|:----:|:-----------------:|:-----------------:|:-----------------:|
| **方向** | 固定(编程设定) | 固定(编程设定) | 动态可变(输入/输出切换) |
| **同步方式** | 无握手信号 | 3 根联络信号握手 | 5 根联络信号(兼顾输入/输出) |
| **中断** | 无 | 有(INTR) | 有(INTR) |
| **占用 C 口引脚** | 0 个 | 3~5 个 | 5 个(PC3~PC7) |
| **适用场景** | 无条件/条件传送 | 同步数据传输 | 需要双向数据交换 |
| **可用端口** | A、B、C | A(输入/输出)、B(仅输入/输出) | 仅 A |
### 4. 三种工作方式详解
#### 方式 0 — 基本输入/输出(编程设定方向)
最简单的工作方式,无需任何联络信号(握手信号),CPU 可直接通过 `IN`/`OUT` 指令读写端口。
- A、B、C 三个端口均可工作在此方式下
- 适用于无条件传送或简单的外设控制(如 LED、开关)
#### 方式 1 — 选通输入/输出
利用端口 C 的部分引脚作为 **联络信号**(握手信号),实现 CPU 与外设之间的同步数据传输。
**方式 1 输入时的联络信号(以 A 口为例):**
| 信号 | 方向 | 含义 |
|------|------|------|
| **STB** (PC4) | 外设 → 8255A | 选通信号,低电平有效,将数据锁存到输入锁存器 |
| **IBF** (PC5) | 8255A → 外设 | 输入缓冲器满,高电平有效,通知外设数据已被接收 |
| **INTRA** (PC3) | 8255A → CPU | 中断请求,请求 CPU 读取数据 |
| **INTE A** | 内部触发器 | 通过 PC4 的置位/复位控制,决定是否允许中断 |
**方式 1 输出时的联络信号(以 A 口为例):**
| 信号 | 方向 | 含义 |
|------|------|------|
| **OBF** (PC7) | 8255A → 外设 | 输出缓冲器满,低电平有效,通知外设数据已准备好 |
| **ACK** (PC6) | 外设 → 8255A | 应答信号,低电平有效,外设确认已取走数据 |
| **INTRA** (PC3) | 8255A → CPU | 中断请求,通知 CPU 可以写入下一个数据 |
> [!info] 方式 1 工作流程(输入)
> 外设准备数据 → 发 STB 锁存数据 → 8255A 发 IBF → 条件满足时发 INTR → CPU 响应中断并读数据 → IBF 变低 → 准备接收下一个数据。
##### 方式 1 的 INTE 控制触发器(重点难点)
方式 1 下,每个端口是否允许向 CPU 发出中断请求,由 **INTE 控制触发器**决定。**INTE 通过 C 口按位控制字来置 0/置 1**:
| INTE | 控制的端口 | 操作端口 C 的位 | 功能 |
|------|-----------|---------------|------|
| **INTE1** | A 口输出 | PC6 | 1=允许 OBF 产生中断 |
| **INTE2** | A 口输入 | PC3 | 1=允许 INTRA 产生中断 ⚠️ 不可直接设置 |
| **INTE3** | B 口输入/输出 | PC1 | 1=允许产生中断 ⚠️ 不可直接设置 |
| **INTE4** | B 口输出 | PC0 | 1=允许产生中断 |
| **INTE5** | A 口双向(方式 2) | PC4 | 1=允许 STB/OBF 相关中断 |
> [!warning] 易错点
> - INTE2 和 INTE3 **无法通过 C 口按位控制字直接置位**!这是 8255A 的硬件限制。
> - 实际编程中,若需要启用 A 口输入中断(INTE2),需通过其他方式(如先配置为方式 0)间接实现。
> - 考试中常考查某一口中断信号的产生条件,必须同时满足:**INTR 有效 AND INTE = 1**。
#### 方式 2 — 双向总线方式(仅端口 A)
**仅端口 A 可用**,同一端口既可输入又可输出,利用端口 C 的 5 个引脚(PC3~PC7)作为联络信号。
```mermaid
flowchart LR
Device["外设"] -- "输入: STB/IBF + 数据" --> PIA["8255A\n端口 A"]
PIA -- "输出: OBF/ACK + 数据" --> Device
PIA -- "INTR 中断请求" --> CPU["CPU"]
```
### 6. 控制字格式
8255A 有两类控制字,通过 **D7 位** 区分,写入同一个端口地址(控制口):
#### 方式控制字(D7 = 1)
用于设置各端口的工作方式和输入/输出方向。
```
D7 D6 D5 D4 D3 D2 D1 D0
1 [A组方式] [A口] [C口高] [B组方式] [B口] [C口低]
↑ ↑ ↑ ↑ ↑ ↑
00=方式0 1=入 1=入 0=方式0 1=入 1=入
01=方式1 0=出 0=出 1=方式1 0=出 0=出
10=方式2
```
**速算技巧**:先确定 D7=1,然后按"A 组方式 → A 口方向 → C 高方向 → B 组方式 → B 口方向 → C 低方向"依次填入。
> [!example] 典型控制字计算
> **要求**:A 口方式 0 输出,B 口方式 0 输出
>
> 分析:D7=1, D6D5=00(方式 0), D4=0(输出), D3=0(输出), D2=0(方式 0), D1=0(输出), D0=0(输出)
>
> 控制字 = `1000 0000B` = **80H**
#### C 口按位置位/复位控制字(D7 = 0)
用于对端口 C 的 **某一位** 进行置 1 或清 0 操作,而不影响其他位。
```
D7 D6 D5 D4 D3 D2 D1 D0
0 × × × [位号选择] [1=置位, 0=复位]
000=PC0
001=PC1
...
111=PC7
```
> [!example] 典型位控制字计算
> **要求**:使 PC3 = 1
>
> 分析:D7=0, D6D5D4 无关(填 0), D3D2D1=011(选 PC3), D0=1(置位)
>
> 控制字 = `0000 0111B` = **07H**
##### C 口引脚复用关系表(考试重点)
方式 1/2 下,端口 C 的部分引脚被用作联络信号,此时不能再当作普通 I/O 使用:
| 端口配置 | 占用的 C 口引脚 | 说明 |
|----------|----------------|------|
| A 口方式 1 输入 | STB(PC4)、IBF(PC5)、INTRA(PC3) | 3 根握手线 |
| A 口方式 1 输出 | OBF(PC7)、ACK(PC6)、INTRA(PC3) | 3 根握手线 |
| A 口方式 2 | STB(PC4)、IBF(PC5)、OBF(PC7)、ACK(PC6)、INTRA(PC3) | 5 根双向握手线 |
| B 口方式 1 输入 | STB(PC1)、IBF(PC0)、INTRA(PC2) | 3 根握手线 |
| B 口方式 1 输出 | OBF(PC1)、ACK(PC0)、INTRA(PC2) | 3 根握手线 |
> [!info] 规律记忆
> - 每个方式 1 端口固定占用 **3 根 C 口引脚**
> - 方式 2 额外增加 2 根 → 共 **5 根**
> - B 口的联络信号全部来自 C 口低 3 位(PC0~PC2),因此 **B 口方式 1 不影响 C 口高 4 位**!这是一个常见考点。
> [!question] 关键考点
> 方式控制字和 C 口位控制字写入的是 **同一个端口地址**(控制口),如何区分?
>
> 答:通过 D7 位区分。D7=1 是方式控制字,D7=0 是位控制字。
### 7. 端口地址推算
8255A 占用 **4 个连续的奇地址**(注意不是按 +1),由 A1、A0 引脚选择。
| A1 A0 | 选中端口 | 相对偏移 |
|:------:|:--------:|:--------:|
| 0 0 | 端口 A | 基地址 + 0 |
| 0 1 | 端口 B | 基地址 + 2 |
| 1 0 | 端口 C | 基地址 + 4 |
| 1 1 | 控制口 | 基地址 + 6 |
> [!info] 为什么地址间隔是 +2?
> 8255A 的 A0、A1 连接到系统地址总线的 **A2、A3**(最低两位被跳过)。系统地址是按字节编址的,8255A 内部不需要 A0/A1 来区分这 4 个寄存器(仅用 2 位 A2/A3 即可),因此地址间距为 **+2**。这个特性在地址推算题中非常关键,很多考生会错误地按 +1 递增计算。
> [!example] 地址推算示例
> **例 1**:已知 A 口地址 = 2F0H
> - B 口 = 2F0H + 2 = **2F2H**
> - C 口 = 2F0H + 4 = **2F4H**
> - 控制口 = 2F0H + 6 = **2F6H**
>
> **例 2**:已知 A 口地址 = 20H(小地址系统)
> - B 口 = 20H + 2 = **22H**
> - C 口 = 20H + 4 = **24H**
> - 控制口 = 20H + 6 = **26H**
### 8. 初始化编程模板
########## 步骤分解
8255A 初始化只需要 **一步**——向控制口写入方式控制字。后续如果需要单独控制 C 口的某一位(如握手信号线),再写入位控制字即可。
```asm
; ============================================
; 场景:A 口方式 0 输出接 LED,B 口方式 0 输入接开关
; 假设 I/O 基地址从 280H 开始
; ============================================
MOV DX, 286H ; 控制口地址 = 280H + 6
MOV AL, 81H ; 1000 0001B:A口方式0输出 + B口方式0输入
OUT DX, AL ; 写入方式控制字 → 完成全部配置
; ★ 关键理解:方式控制字一次性设定了所有端口的工作方式和方向
; ★ 不需要分别对 A/B/C 口进行设置
```
#### C 口按位置位/复位(配合使用)
当需要对 C 口的**某一位**进行精确控制时(比如拉高/拉低某个握手信号):
```asm
; 使 PC5 = 1(常用于将 IBF 置高,准备接收数据)
MOV DX, 286H ; 控制口地址不变
MOV AL, 22H ; 0000 0101B:D7=0 表示位控制字,PC5 选位,D0=1 置位
OUT DX, AL ; 仅改变 PC5,不影响其他 C 口引脚
; 使 PC5 = 0(清 0)
MOV AL, 20H ; 0000 0100B:同样是 PC5 选位,但 D0=0 复位
OUT DX, AL
```
> [!tip] 位控制字速查表
> | 目标 | 十六进制值 | 二进制 |
> |------|-----------|--------|
> | PC0 = 1 | **01H** | `0000 0001` |
> | PC1 = 1 | **03H** | `0000 0011` |
> | PC2 = 1 | **05H** | `0000 0101` |
> | PC3 = 1 | **07H** | `0000 0111` |
> | PC4 = 1 | **09H** | `0000 1001` |
> | PC5 = 1 | **0BH** | `0000 1011` |
> | PC6 = 1 | **0DH** | `0000 1101` |
> | PC7 = 1 | **0FH** | `0000 1111` |
#### 综合示例:A 口方式 1 输入 + B 口方式 0 输出
```asm
; 已知基地址 = 300H,A 口方式 1 输入(INTE2=1),B 口方式 0 输出
; ① 先启用 A 口输入中断的允许触发器(INTE2)
; INTE2 对应通过 PC3 间接控制 → 用位控制字设 PC3=1
MOV DX, 306H
MOV AL, 07H ; 0000 0111B:选 PC3,置 1
OUT DX, AL ; ⚠️ 但注意:INTE2 实际上无法直接通过位控制字设置!
; 这里仅为演示流程,实际工程中需另行处理。
; ② 写入方式控制字
MOV AL, 1010 0000B ; D7=1, A组=1(方式1), A口=1(输入), C高=0(输出)
; B组=0(方式0), B口=0(输出), C低=0(输出)
; = 1010 0000B = A0H
MOV DX, 306H
OUT DX, AL
```
> [!warning] 易错点
> 1. **控制字只写一次**:不要反复向控制口写入相同的方式控制字。初始化完成后只需在需要时修改 C 口状态才写入位控制字。
> 2. **DX 寄存器必须配合**:`OUT` 指令中,端口地址≥256(即扩展寻址)时必须放在 DX 中,否则只能访问 0~255(FFH)。
> 3. **先写位控制字还是先写方式控制字**?若需设置 INTE 触发器,需**先**写入位控制字打开中断允许,**再**写入方式控制字选择工作模式。
## 练习题集(考前自测)
### 题 1:控制字计算(★)
> **题目**:A 口方式 0 输出,B 口方式 0 输入。求方式控制字。
<details>
<summary>查看答案</summary>
- D7 = 1(方式控制字标识)
- D6D5 = 00(A 组方式 0)
- D4 = 0(A 口输出)
- D3 = 0(C 高位置位/复位,无意义)
- D2 = 0(B 组方式 0)
- D1 = 1(B 口输入)
- D0 = 0(C 低位置位/复位,无意义)
**答案**:`1000 0010B` = **82H**
</details>
### 题 2:地址推算(★★)
> **题目**:已知 8255A 的基地址为 2F0H,请写出 A、B、C 三个端口及控制口的地址。
<details>
<summary>查看答案</summary>
| 端口 | 地址 | 计算过程 |
|------|------|---------|
| A 口 | **2F0H** | 基地址 + 0 |
| B 口 | **2F2H** | 基地址 + 2 |
| C 口 | **2F4H** | 基地址 + 4 |
| 控制口 | **2F6H** | 基地址 + 6 |
</details>
### 题 3:综合编程(★★★)
> **题目**:设计一个接口电路,A 口方式 1 输入接键盘数据,B 口方式 0 输出接 LED 显示。I/O 基地址为 300H。编写初始化程序。
<details>
<summary>查看答案</summary>
```asm
; ★ 第一步:启用 INTE2(允许 A 口输入中断)
; INTE2 对应 PC3 → 需要写位控制字设 PC3=1
MOV DX, 306H ; 控制口地址 = 300H + 6
MOV AL, 07H ; 位控制字:选 PC3,置 1
OUT DX, AL ; 设置 INTE2=1
; ★ 第二步:写入方式控制字
; D7=1, D6D5=1(A组方式1), D4=1(A口输入), D3=0,
; D2=0(B组方式0), D1=0(B口输出), D0=0
; = 1010 0000B = A0H
MOV AL, 0A0H ; 修正写法,更清晰
MOV DX, 306H
OUT DX, AL ; 完成 8255A 初始化
```
> [!tip] 要点总结
> 1. 必须先启用 INTE(通过位控制字),再写方式控制字
> 2. A 口方式 1 输入占用 PC3、PC4、PC5;B 口方式 0 不受影响
> 3. 所有配置均写入同一个控制口地址
</details>
### 题 4:C 口引脚复用判断(★★)
> **题目**:A 口工作于方式 2,此时端口 C 还有哪些引脚可作为普通 I/O 使用?
<details>
<summary>查看答案</summary>
方式 2 下,端口 A 占用 PC3~PC7(STB、IBF、OBF、ACK、INTRA),因此:
- **PC0、PC1、PC2** 仍可作为普通 I/O 使用
- **PC3~PC7** 被握手信号占用,不可用作普通 I/O
</details>
### 题 5:INTE 触发器(★★)
> **题目**:以下哪种情况可以产生 A 口方式 1 输入中断?
>
> A. INTR 有效且 INTE2 = 0
> B. INTR 无效且 INTE2 = 1
> C. INTR 有效且 INTE2 = 1
> D. 任意状态均可
<details>
<summary>查看答案</summary>
**正确答案:C**
中断产生的条件是 **两个条件同时满足**:
1. INTR 引脚为高电平(请求信号有效)
2. INTE2 = 1(中断允许触发器使能)
缺少任何一个条件都无法产生中断请求。这是考试中常见的选择题考点。
</details>
## 知识总结
- **4 个端口地址**:基址 + {0, 2, 4, 6} → A / B / C / 控制口(间隔为 2!)
- **3 种工作模式**:方式 0(基本)、方式 1(选通)、方式 2(双向)
- **2 类控制字**:方式控制字(D7=1)、C 口按位控制字(D7=0)
- **关键关系**:每个方式 1 占用 C 口 3 引脚,方式 2 占用 5 引脚
---
## 关联笔记
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]
- [[接口与通讯技术/试题册/index|试题册索引]]