Files
final-exam/接口与通讯技术/复习文档/8259A中断控制器.md
T

470 lines
19 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:
- 接口与通讯技术
- 8259A
- 中断控制器
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8259A 中断控制器
## 概述
8259A 是 Intel 公司生产的可编程中断控制器(Programmable Interrupt Controller, PIC),**在全部 4 套试卷中均有出现**。它负责管理和控制 8086 系统中的外部中断请求,支持 8 级优先级中断,可通过级联扩展至最多 64 级。本芯片的知识点主要集中在 **初始化命令字(ICW)编写**、**中断响应过程** 和 **优先级管理** 三个方面。
> [!tip] 考试要点
> - **ICW 写入顺序**:ICW1 → ICW2 → ICW3(可选)→ ICW4(可选)
> - **ICW2 与中断类型码**的计算:高 5 位由程序员设定,低 3 位自动对应 IR0~IR7
> - **中断响应时序**:两个 INTA 脉冲期间 8259A 分别执行什么操作
> - **OCW2 EOI 命令**的发送方式和端口
> - **全嵌套方式**的优先级规则和适用场景
> - **级联系统**的中断级数和 ICW3 设置
## 正文
### 1. 8259A 的核心功能
```mermaid
graph TB
A["IR0~IR7 中断请求输入"] --> B["8259A"]
B -- "INT 输出" --> C["CPU"]
C -- "INTA 响应" --> B
B -- "中断类型码" --> C
D["优先级判别器 PR"] <--> B
E["中断屏蔽寄存器 IMR"] <--> B
F["中断服务寄存器 ISR"] <--> B
G["中断请求寄存器 IRR"] <--> B
```
| 寄存器 | 缩写 | 位数 | 功能说明 |
|--------|------|:----:|------|
| 中断请求寄存器 | **IRR** | 8 位 | 记录哪些 IR 引脚有pending的中断请求,某位 = 1 表示对应 IRi 有未响应的请求 |
| 中断屏蔽寄存器 | **IMR** | 8 位 | 某位 = 1 则屏蔽对应 IR 的中断请求(通过 OCW1 设置),= 0 则允许 |
| 中断服务寄存器 | **ISR** | 8 位 | 记录当前正在被 CPU 服务的中断源,用于嵌套管理;中断服务完成后需清除 |
| 优先级判别器 | **PR** | — | 从 IRR 中未被 IMR 屏蔽的请求里选出最高优先级的中断 |
> [!question] IRR、IMR、ISR 三者如何协作完成一次中断响应?
> 1. 外设在 IRi 引脚产生中断请求 → **IRR** 对应位置 1
> 2. 8259A 将 IRR 与 **IMR** 做按位与运算:某位 = IMR 该位的值 → 该请求被屏蔽,不可响应
> 3. 未被屏蔽的请求送入 **PR** 进行优先级判别,选出的最高优先级候选与 **ISR** 比较
> 4. 若候选优先级高于 ISR 中所有正在服务的中断,则 8259A 向 CPU 发出 **INT** 信号
> 5. CPU 响应后给出两个 **INTA** 脉冲 → 第一个 INTA 将 ISR 对应位置 1、IRR 对应位清 0;第二个 INTA 将中断类型码送上数据总线
### 2. 端口地址
8259A 有两个端口地址,取决于总线地址线 **A0** 的值:
| A0 | 端口用途 | 最小系统中地址 |
|----|----------|:--------------:|
| 0 | **偶地址端口** — 写 ICW1、OCW2、OCW3;读 ISR / IRR | **20H** |
| 1 | **奇地址端口** — 写 ICW2、ICW3、ICW4、OCW1 | **21H** |
> [!info] 端口地址记忆法
> - A0 = 0 → 偶地址 → 20H("偶"和"零"都联想为偶数)
> - A0 = 1 → 奇地址 → 21H(比 20H 大 1,刚好对应 A0=1)
> - 最小系统中 8259A 的端口就是 20H/21H,考试默认使用此地址
### 3. 初始化命令字(ICW)
8259A 上电后必须通过 ICW 完成初始化,**必须按顺序写入**,每个命令字占一个 I/O 写周期:
```mermaid
graph LR
A["ICW1\n(偶地址端口 A0=0)"] --> B{"ICW1 的 D1 SNGL"}
B -- "0: 级联模式" --> C["ICW2\n(奇地址端口)"]
B -- "1: 单片模式" --> C
C --> D["ICW3\n(仅级联时写)"]
D --> E["ICW4\n(按需)"]
E --> F["初始化完成"]
```
#### ICW1(偶地址端口,A0=0)
```
D7 D6 D5 D4 D3 D2 D1 D0
[ Don't Care ] 1 LTIM: 0=边沿触发 1=电平触发 SNGL: 0=级联 1=单片 IC4: 0=不需ICW4 1=需ICW4
```
| 位 | 符号 | 含义 | 说明 |
|---|------|------|------|
| D4 | — | **固定为 1** | 这是识别 ICW1 的标志位,若 D4=0 则视为 OCW 而非 ICW |
| D3 | LTIM | 触发方式 | 0 = 边沿触发(IR 上升沿有效);1 = 电平触发(IR 高电平有效) |
| D2 | SNGL | 级联标志 | 0 = 多片级联(后续需要写 ICW3);1 = 单片系统(不写 ICW3) |
| D0 | IC4 | ICW4 标志 | 0 = 不需要 ICW4(默认工作在 8080/8085 模式);1 = 需要 ICW4(8086 模式下必须写) |
> [!example] ICW1 计算示例
> **要求**:边沿触发、级联方式、需要 ICW4
>
> - D4 固定 = 1
> - LTIM = 0(边沿触发)
> - SNGL = 0(级联)
> - IC4 = 1(需要 ICW4)
> - D7~D5 可填 0
>
> ICW1 = `0001 0001B` = **11H**
#### ICW2(奇地址端口,A0=1)
ICW2 提供 **中断类型码的高 5 位**(T7~T3),低 3 位(T2~T0)由 8259A **根据请求来源自动填入**。
```
D7 D6 D5 D4 D3 D2 D1 D0
T7 T6 T5 T4 T3 固定为 0 (IR 编码会自动填充)
```
中断类型码的计算公式:
$$
\text{类型码} = \text{ICW2}_{[7:3]} \times 2^3 + \text{IR编号}
$$
即:ICW2 高 5 位左移 3 位,再加上 IR 引脚号(0~7)。
> [!example] ICW2 计算示例
>
> **例 1**:IR0~IR7 对应中断类型码 80H~87H
> - 80H = `1000 0000B`,高 5 位 = `10000`
> - ICW2 = **80H**
> - 验证:IR0 → 80H, IR1 → 81H, ..., IR7 → 87H ✓
>
> **例 2**:IR0~IR7 对应中断类型码 20H~27H
> - 20H = `0010 0000B`,高 5 位 = `00100`
> - ICW2 = **20H**
>
> **例 3**:IR0~IR7 对应中断类型码 48H~4FH
> - 48H = `0100 1000B`,高 5 位 = `01001`
> - ICW2 = **90H** (注意:取高 5 位而不是取原字节!48H 的高 5 位是 `01001` = 9H,所以 ICW2 = 90H)
> [!warning] 易错点
> ICW2 的值不等于第一个中断类型码!ICW2 只保留高 5 位,低 3 位填 0。例如要分配 48H~4FH,ICW2 = 90H(不是 48H)。这是因为低 3 位由 IR 编号自动填入。
#### ICW3(奇地址端口,仅级联时需要)
ICW3 在主片和从片中有不同含义:
- **主片 ICW3**:每位对应一个 IR 引脚,某位 = 1 表示该 IR 引脚连接了从片的 INT 输出
- 例如 IR2 和 IR5 各接一个从片 → 主片 ICW3 = `0010 0100B` = **24H**
- **从片 ICW3**:低 3 位表示从片的 INT 接到主片的哪个 IR 引脚(即从片的 ID 编号)
- 例如从片接到主片 IR2 → 从片 ICW3 = `0000 0010B` = **02H**
> [!example] 一主二从级联的 ICW3 设置
>
> - 主片 IR2 接从片 1,IR5 接从片 2
> - 主片 ICW3 = IR2 + IR5 = `0010 0100B` = **24H**
> - 从片 1 ICW3 = 2(接到主片 IR2)= **02H**
> - 从片 2 ICW3 = 5(接到主片 IR5)= **05H**
#### ICW4(奇地址端口,按需)
```
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 SFNM: BUF: M/S: uPM: (保留=0)
0=普通 0=非缓冲 0=从片 0=8080/8085
1=特殊全嵌套 1=缓冲 1=主片 1=8086/8088
```
| 位 | 符号 | 含义 |
|---|------|------|
| D4 | SFNM | **Special Fully Nested Mode**,特殊全嵌套方式。当系统中有多片 8259A 级联且其中一片本身也有子级联时使用,该片的 ISR 允许同级中断嵌套 |
| D3 | BUF | **Buffer Flag**,缓冲模式标志。= 1 表示系统使用缓冲区(通常配合 82283 收发器),此时需结合 M/S 位决定选择器;= 0 为非缓冲直接连接 |
| D2 | M/S | Master/Slave,仅当 BUF=1 时有效。= 1 为主片(选择器输出使能);= 0 为从片 |
| D0 | uPM | **Unified Protected Mode**,CPU 模式。= 1 表示 8086/8088 模式(自动 EOI 禁用);= 0 表示 8080/8085 模式 |
> [!warning] 8086 系统中 ICW4 必须写
> 8086/8088 系统下,ICW4 的 D0 = uPM = 1 是必须的。考试中常见最小初始化序列为:**ICW1 → ICW2 → ICW4**(跳过 ICW3)。
> [!example] ICW4 计算示例
> **要求**:8086 模式,非缓冲方式
> - D7~D5 = 000
> - SFNM = 0(普通模式)
> - BUF = 0(非缓冲)
> - M/S = 0(不考虑,BUF=0 时无效)
> - uPM = 1(8086 模式)
> - D0 = 0(保留位)
>
> ICW4 = `0000 0010B` = **02H**
>
> **要求**:8086 模式,缓冲方式,主片
> - BUF = 1, M/S = 1, uPM = 1
> - ICW4 = `0000 1110B` = **0EH**
### 4. 操作命令字(OCW)
OCW 在初始化完成后、系统运行过程中根据需要写入,可随时修改:
| OCW | 端口 | 可读写 | 功能 |
|-----|------|:------:|------|
| **OCW1** | 奇地址 (A0=1) | 仅写 | 设置中断屏蔽字,直接写入 IMR。某位 = 1 屏蔽对应中断 |
| **OCW2** | 偶地址 (A0=0) | 仅写 | 控制中断结束方式和优先级轮换策略 |
| **OCW3** | 偶地址 (A0=0) | 读写 | 查询 RR/RIS 状态、设置特殊屏蔽方式 |
#### OCW2 — EOI 命令
```
D7 D6 D5 D4 D3 D2 D1 D0
0 0 R SL EOI (reserved)
```
三种常用操作:
| 操作 | D1 D0 | D2 | 说明 | 示例值 |
|------|:-----:|:--:|------|:------:|
| **普通 EOI** | xx | 0 | 置 EOI=1, R=SL=0 → 清除 ISR 中优先级最高的位 | **20H** |
| **特殊 EOI** | 0x | 1 | 置 EOI=1, R=0, SL=1 → 指定清除 ISR 中 IRk 对应的位(k 由 D4~D2 指定) | **C0H**(清除 IR0)|
| **优先级自动循环** | 10 | 0 | 设 R=1, SL=0, EOI=0 → 服务完后最高优先级降为最低,次高变为最高 | **A0H** |
> [!info] EOI 命令怎么发?
> OCW2 写入**偶地址端口**(最小系统 = 20H)。在中断服务程序末尾发送 EOI 以通知 8259A 该中断处理完毕:
> ```asm
> MOV AL, 20H ; 普通 EOI
> OUT 20H, AL ; 发送到偶地址端口
> ```
> [!question] 为什么要发送 EOI?
> 发送 EOI 后,8259A 会将 ISR 中对应中断源的位清 0。不清 0 的话,8259A 认为该中断仍在服务,不会响应相同或更低优先级的中断。只有在自动 EOI 模式(某些特定配置下)才不需要手动发送 EOI。
#### OCW3 — 特殊屏蔽方式和读命令
OCW3 的功能较多样:
- **设置特殊屏蔽方式(ESMM = 1)**:某位 = 1 时进入特殊屏蔽方式,此时 IMR 的该位 = 1 允许同级别中断嵌套(只屏蔽比当前低的)
- **设置 RR/RIS 读取命令**:RR=1 时,下一个 INTA 脉冲读出 ISR(RR=1, RIS=1)或 IRR(RR=1, RIS=0)的内容
- **查询 polled 命令**:用于轮询方式查找最高优先级挂起中断
### 5. 中断响应过程
```mermaid
sequenceDiagram
participant P as "外设"
participant I as "8259A"
participant C as "CPU"
P->>I: "IRi 引脚产生中断请求"
Note over I: "IRR[i] = 1"
Note over I: "PR 判别优先级"
I->>C: "INT = 1 (向 CPU 发中断请求)"
C->>I: "第一个 INTA 脉冲"
Note over I: "ISR[i] = 1<br/>IRR[i] = 0<br/>8259A 锁存当前优先级"
C->>I: "第二个 INTA 脉冲"
I->>C: "中断类型码 N 送上数据总线"
Note over C: "CPU 读类型码 N"
Note over C: "向量地址 = N × 4"
C->>C: "从向量表读取 CS:IP<br/>转去执行中断服务程序"
```
> [!warning] 两个 INTA 脉冲的作用截然不同
> - **第一个 INTA**:8259A 内部操作 —— 将被响应当前中断置入 ISR、从 IRR 中清除对应位,并锁定当前优先级以防止同级中断干扰。此时 CPU 尚未获取类型码。
> - **第二个 INTA**:8259A 将锁存的中断类型码(已拼接好的完整 8 位类型码)放到数据总线上供 CPU 读取。
### 6. 中断向量表
8086 的中断向量表位于内存最低地址 **00000H ~ 003FFH**(共 1KB),可存放 256 个中断向量(每个向量 4 字节)。
中断向量地址计算公式:
$$
\text{向量地址} = \text{中断类型号} \times 4
$$
每个向量占 4 字节,布局为:**低 2 字节 = IP(偏移地址),高 2 字节 = CS(段地址)**。
| 向量地址 | 存储内容 | 说明 |
|---------|----------|------|
| N×4 | IP 低字节 | 跳转目标偏移 |
| N×4+1 | IP 高字节 | |
| N×4+2 | CS 低字节 | 跳转目标段 |
| N×4+3 | CS 高字节 | |
> [!example] 中断向量表地址计算
>
> **例**:中断类型码为 80H,其向量存放在哪里?
> - 向量地址 = 80H × 4 = `10000000₂` × 4 = **200H**
> - 向量存放在 **00000H + 200H = 00200H ~ 00203H** 四个字节
> - 00200H = IP 低字节, 00201H = IP 高字节, 00202H = CS 低字节, 00203H = CS 高字节
### 7. 优先级管理方式
| 方式 | 特点 | 优先级变化 | 配置方法 |
|------|------|-----------|---------|
| **固定优先级**(默认,全嵌套) | IR0 最高 → IR7 最低,永远不变 | 无变化 | 默认工作模式 |
| **自动优先级轮换** | 服务完的中断降为最低,原来的最低升到最高 | 循环移动 | OCW2 = A0H(编程旋转) |
| **特殊全嵌套** | 允许**同级**中断嵌套,用于级联系统中主片 | 无变化 | ICW4 的 SFNM=1 |
| **特殊屏蔽方式** | 临时屏蔽当前优先级,只允许更低优先级中断 | 按需切换 | OCW3 设置 ESMM + SIM |
> [!question] 全嵌套方式下,IRQ5 正在服务,哪些中断可以打断它?
> 答:只有优先级更高的 **IRQ0 ~ IRQ4** 可以打断 IRQ5。IRQ6 和 IRQ7 优先级低于 IRQ5,必须等待 IRQ5 服务完成(发送 EOI 清除 ISR[5])后,才能被调度。**即使 IRQ6/IRQ7 没有被 IMR 屏蔽,也不会响应**。
> [!info] 全嵌套 vs 特殊全嵌套
> - **全嵌套**(固定优先级):不同优先级之间可以嵌套,但**同级不能嵌套**
> - **特殊全嵌套**(SFNM=1):同全嵌套一样默认不同级可嵌套,但通过 OCW3 可将某个中断设为特殊屏蔽,允许**同级**中断抢占——这在级联系统的从片中很重要(从片内部可能还需要处理多个同级子中断)
### 8. 级联扩展
| 配置 | 中断级数 | IR 端口占用 | 说明 |
|------|:--------:|------------|------|
| 单片 8259A | **8 级** | 8 | IR0~IR7 均直接使用 |
| 一主一从级联 | **15 级** | 8 + 7 = 15 | 从片占用主片 1 个 IR(8+8-1=15) |
| 一主二从级联 | **22 级** | 8 + 7 + 7 = 22 | 两个从片各占用主片 1 个 IR |
| 四片级联(1主3从) | **29 级** | 8 + 7×3 = 29 | 最多扩展到 64 级(4 片 8259A) |
> [!info] 为什么是 8n-1 而不是 8n?
> 每增加一片从片,需要占用主片(或上级从片)的一个 IR 端口来传递从中继而来的中断请求,因此实际可用的中断级数 = 8×N - (N-1) = 7N + 1,其中 N 为 8259A 片数。第一片贡献 8 级,之后每加一片净增 7 级。
### 9. 典型初始化程序
以下是一个完整的初始化示例(最小系统,8086 模式):
```asm
; ============================================================
; 8259A 初始化程序(最小系统)
; 端口地址:20H(偶地址,A0=0),21H(奇地址,A0=1)
; 条件:边沿触发、单片、中断类型码 80H~87H、8086 模式
; ============================================================
MOV AL, 11H ; ICW1: 边沿触发(LTIM=0), 单片(SNGL=1), 需ICW4(IC4=1)
; 0001 0001B = 11H
OUT 20H, AL ; 写入偶地址端口
MOV AL, 80H ; ICW2: 中断类型码基址 = 80H(高5位=10000)
OUT 21H, AL ; 写入奇地址端口
; IR0→80H, IR1→81H, ..., IR7→87H
MOV AL, 02H ; ICW4: 8086模式(uPM=1), 非缓冲
; 0000 0010B = 02H
OUT 21H, AL ; 写入奇地址端口
; ---- 初始化完成 ----
; 此时 IMR = 00H(复位默认值),所有中断开放
```
#### 中断服务程序模板
```asm
INT_ISR PROC FAR
PUSH AX ; 保护现场
PUSH BX
PUSH CX
PUSH DX
PUSH DS
; ---- 中断处理逻辑 ----
; ... 具体处理代码 ...
MOV AL, 20H ; 普通 EOI 命令
OUT 20H, AL ; 发送到 8259A(偶地址端口)
POP DS ; 恢复现场
POP DX
POP CX
POP BX
POP AX
IRET ; 中断返回(从栈中恢复 CS:IP 和 FLAGS)
INT_ISR ENDP
```
> [!info] IRET vs RET 的区别
> - **RET**:普通子程序返回,只弹出 IP
> - **IRET**:中断返回,依次弹出 IP → CS → FLAGS,恢复中断前的完整上下文
### 10. 考试综合例题
> [!example] 【真题型】设计 8259A 初始化程序
>
> **题目**:某 8086 系统中使用单片 8259A,端口地址 20H/21H,要求:
> - 边沿触发
> - 中断类型码起始于 70H
> - 工作在 8086 模式
> - 初始化后允许所有中断
>
> **解答**:
> ```asm
> MOV AL, 70H ; ICW2: 中断类型码基址 = 70H(高 5 位 = 01110)
> ; IR0→70H, IR1→71H, ..., IR7→77H
> OUT 21H, AL
>
> MOV AL, 02H ; ICW4: 8086 模式 (uPM=1), 非缓冲
> OUT 21H, AL
>
> MOV AL, 00H ; OCW1: 不屏蔽任何中断(所有中断开放)
> OUT 21H, AL
> ```
> [!tip] ICW2 取值要点
> ICW2 的值就是 **IR0 对应的中断类型码**。例如题目要求中断类型码从 70H 开始,ICW2 直接设为 70H 即可。这是因为 ICW2 的高 5 位构成类型码的高 5 位,低 3 位自动为 0,恰好对应 IR0(编号为 0)。
---
> [!question] 【综合题】多片级联系统初始化
>
> **题目**:某 8086 系统采用一主两从级联方式,端口地址 20H/21H,要求:
> - 边沿触发
> - 主片 IR2 接从片 1,IR5 接从片 2
> - 所有芯片中断类型码分别起始于 40H、50H、60H
> - 工作在 8086 模式、缓冲方式
>
> **解答**:
>
> **主片初始化**:
> ```asm
> MOV AL, 13H ; ICW1: 边沿(0), 级联(0), 需ICW4(1) → 0001_0011B = 13H
> OUT 20H, AL
> MOV AL, 40H ; ICW2: 主片类型码基址 = 40H
> OUT 21H, AL
> MOV AL, 24H ; ICW3: IR2+IR5 = 0010_0100B = 24H
> OUT 21H, AL
> MOV AL, 0EH ; ICW4: 8086模式(uPM=1), 缓冲(BUF=1), 主片(M/S=1) = 0000_1110B = 0EH
> OUT 21H, AL
> ```
>
> **从片 1 初始化**:
> ```asm
> MOV AL, 11H ; ICW1: 边沿(0), 单片(1), 需ICW4(1) = 0001_0001B = 11H
> OUT 20H, AL
> MOV AL, 50H ; ICW2: 从片1类型码基址 = 50H
> OUT 21H, AL
> MOV AL, 02H ; ICW3: 接主片IR2 → ID=2 = 00H
> OUT 21H, AL
> MOV AL, 0AH ; ICW4: 8086模式, 缓冲, 从片(M/S=0) = 0000_1010B = 0AH
> OUT 21H, AL
> ```
>
> **从片 2 初始化**:
> ```asm
> MOV AL, 11H ; ICW1: 同从片1
> OUT 20H, AL
> MOV AL, 60H ; ICW2: 从片2类型码基址 = 60H
> OUT 21H, AL
> MOV AL, 05H ; ICW3: 接主片IR5 → ID=5 = 05H
> OUT 21H, AL
> MOV AL, 0AH ; ICW4: 8086模式, 缓冲, 从片(M/S=0) = 0AH
> OUT 21H, AL
> ```
>
> > [!info] 解题思路
> > 1. 先确认级联方式 → SNGL=0 → 需要 ICW3
> > 2. 确定 ICW2 = 各芯片中断类型码的起始值(IR0 对应的类型码)
> > 3. 主片 ICW3 = 连接从片的 IR 引脚编号之和
> > 4. 从片 ICW3 = 连接到主片的 IR 引脚编号(即自身 ID)
> > 5. 缓冲模式下,ICW4 中 BUF=1,M/S 区分主从片
> [!question] 【选择题风格】8259A 在最小系统中的端口地址是多少?
> A) 20H/21H B) 22H/23H C) 28H/29H D) 30H/31H
>
> 答:**A) 20H/21H**。这是标准答案,考试默认使用该地址。
## 附录:快速复习卡
> [!summary] 核心口诀
> - **ICW 顺序记心中**:ICW1 → ICW2 → ICW3(级联) → ICW4(8086必写)
> - **奇偶分清单又明**:偶地址(20H)写 ICW1/OCW2/OCW3,奇地址(21H)写 ICW2/3/4 和 OCW1
> - **ICW2 高位我设定**:高 5 位自己填,低 3 位自动对应 IR 号
> - **EOI 必须手动发**:OCW2=20H 送 20H,别忘写在 ISR 末尾
> - **全嵌套高低分明**:IR0 永远最高,IR7 永远最低
## 关联笔记
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8251A串行通信接口]]
- [[接口与通讯技术/试题册/index|试题册索引]]