vault backup: 2026-06-26 23:22:55

This commit is contained in:
2026-06-26 23:22:56 +08:00
parent f0272e1ceb
commit b5ab951ca8
9 changed files with 825 additions and 19 deletions
@@ -0,0 +1,195 @@
---
tags:
- 接口与通讯技术
- 8251A
- 串行通信
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8251A 串行通信接口
## 概述
8251A 是 Intel 公司生产的可编程串行通信接口芯片(USART,Universal Synchronous/Asynchronous Receiver/Transmitter),**在试题 A、B、D 中均有出现**。它负责 CPU(并行数据)与串行外设之间的数据格式转换,支持异步和同步两种通信方式。
> [!tip] 考试要点
> - **两个控制字的写入顺序**:先方式控制字,再命令控制字
> - **方式控制字各位含义**:D7D6(波特率因子)、D1D0(数据位)
> - **异步帧格式**:起始位 + 数据位 + 校验位 + 停止位的总位数计算
> - **状态信号**:TXRDY、RXRDY 的含义
## 正文
### 1. 串行通信基础概念
#### 异步通信 vs 同步通信
| 特性 | 异步通信 | 同步通信 |
|------|----------|----------|
| 同步方式 | 起始位/停止位实现字符同步 | 同步字符实现数据块同步 |
| 数据单位 | 逐字符传送 | 以数据块为单位 |
| 传输效率 | 较低(每字符有冗余位) | 较高 |
| 适用场景 | 低速、不连续数据 | 高速、连续数据 |
| 硬件要求 | 简单 | 较复杂 |
#### 异步通信帧格式
```mermaid
graph LR
A["起始位(1)"] --> B["数据位(5~8)"]
B --> C["校验位(0或1)"]
C --> D["停止位(1, 1.5, 2)"]
```
> [!example] 帧长度计算
> 1 位起始 + 8 位数据 + 1 位奇偶校验 + 1 位停止 = **10 位/帧**
>
> 波特率 2400 bps → 每秒最多传输 2400 / 10 = **240 个字符**
#### RS-232C 电平标准
| 逻辑值 | RS-232C 电平 | TTL 电平 |
|:------:|:------------:|:--------:|
| 逻辑 "1" | -3V ~ -15V | +2.4V ~ +5V |
| 逻辑 "0" | +3V ~ +15V | 0V ~ +0.4V |
> [!warning] RS-232C 采用 **负逻辑**,与 TTL 电平 **完全相反**!因此 RS-232C 接口需要电平转换芯片(如 MAX232)。
### 2. 8251A 的两个控制字
8251A 的编程核心是 **两个控制字**,写入顺序不可颠倒:
```mermaid
graph LR
A["硬件/软件复位"] --> B["写入方式控制字"]
B --> C["写入命令控制字"]
C --> D["正常工作"]
D --> E["可随时写入新命令控制字"]
```
#### 工作方式控制字
在复位后 **必须首先写入**,定义通信格式参数:
```
D7 D6 D5 D4 D3 D2 D1 D0
[波特率因子] [校验控制] [停止位] [数据位]
异步模式下:
D7D6: 00=同步 01=x1 10=x16 11=x64
D5D4: 00=无校验 01=奇校验 10=偶校验
D1D0: 00=5位 01=6位 10=7位 11=8位
```
> [!example] 方式控制字计算
> **要求**:异步通信,波特率因子 x16,偶校验,8 位数据
>
> D7D6=10(x16), D5D4=10(偶校验), D3D2=01(1 位停止位), D1D0=11(8 位数据)
>
> 控制字 = `1010 0111B` = **A7H**
>
> ---
>
> **要求**:异步通信,波特率因子 x16,偶校验,8 位数据,1 位停止位
>
> D7D6=01(x1 → 按试卷答案 D7D6=01 即因子 1), D3D2=11, D1D0=11
>
> 控制字 = `0100 1111B` = **4FH**
#### 命令控制字
定义 8251A 的操作行为:
```
D7 D6 D5 D4 D3 D2 D1 D0
EH IR RTS ER SBRK RxE TxD TxEN
0=正常 0 0=RTS高 0 0 0 0 0=禁止
1=内部 1 1=RTS低 1 1 1 1 1=允许
复位
```
各位功能:
| 位 | 符号 | 含义 |
|:--:|------|------|
| D0 | **TxEN** | 发送允许(1=允许发送) |
| D1 | **DTR** | 数据终端准备好(0=DTR 输出低) |
| D2 | **RxE** | 接收允许(1=允许接收) |
| D3 | **SBRK** | 发送 Break 字符 |
| D4 | **ER** | 错误标志复位(1=清除 FE/OE/PE 错误标志) |
| D5 | **RTS** | 请求发送(0=RTS 输出低电平) |
| D6 | **IR** | 内部复位(1=回到等待方式控制字状态) |
| D7 | **EH** | 进入搜索方式(同步模式用) |
> [!example] 命令控制字计算
> **要求**:允许发送和接收,清除错误标志
>
> TxEN=1, RxE=1, ER=1, 其余=0
>
> 命令控制字 = `0001 0101B` = **15H**
### 3. 状态信号
| 信号 | 含义 | 用途 |
|------|------|------|
| **TXRDY** | 发送缓冲器空且允许发送 | 通知 CPU 可以写入新数据 |
| **RXRDY** | 接收缓冲器满 | 通知 CPU 可以读取数据 |
| **TxE** | 发送器空 | 所有数据已发送完毕 |
| **SYNDET/BRKDET** | 同步检测/Break 检测 | 同步模式或 Break 条件 |
> [!question] TXRDY 何时变高?
> 当发送缓冲器空 **且** 命令控制字中 TxEN=1(允许发送)时,TXRDY 变高。CPU 查询到 TXRDY=1 后可以写入下一个待发送的数据字节。
### 4. 引脚功能
| 引脚 | 功能 |
|------|------|
| **TxD** | 发送数据输出 |
| **RxD** | 接收数据输入 |
| **TxC** | 发送时钟(控制发送速率) |
| **RxC** | 接收时钟(控制接收速率) |
| **RTS** | 请求发送(输出,通知外设) |
| **CTS** | 清除发送(输入,外设应答) |
| **DTR** | 数据终端准备好(输出) |
| **DSR** | 数据装置准备好(输入) |
> [!info] 硬件流控制
> RTS/CTS 和 DTR/DSR 两对信号实现硬件握手中的数据流方向控制:
> - 发送方:发 RTS(请求发送)→ 等待 CTS(允许发送)→ 开始发送
> - 接收方:通过 CTS 控制发送方是否可以继续发数据
### 5. 8251A 初始化流程
```asm
; 8251A 完整初始化程序
; 端口地址:04F0H(数据口),04F2H(控制口)
; 步骤 1:确保复位状态
MOV DX, 04F2H ; 控制口
MOV AL, 00H
OUT DX, AL
OUT DX, AL
OUT DX, AL ; 连续写 3 次 00
MOV AL, 40H
OUT DX, AL ; 内部复位命令
; 步骤 2:写方式控制字
MOV AL, 4FH ; 波特率 x16, 偶校验, 8 位数据
OUT DX, AL
; 步骤 3:写命令控制字
MOV AL, 15H ; 允许收发, 清除错误标志
OUT DX, AL
```
> [!danger] 初始化顺序不可乱
> 8251A 硬件复位后处于"等待方式控制字"状态。**必须**先写方式控制字,再写命令控制字。若想重新初始化,需先写命令控制字中 IR=1(40H)进行内部复位,再按顺序重写两个控制字。
## 关联笔记
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[接口与通讯技术/DMA控制器8237A]]
- [[接口与通讯技术/试题册/index|试题册索引]]
@@ -0,0 +1,186 @@
---
tags:
- 接口与通讯技术
- 定时器
- 计数器
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8254 定时计数器
## 概述
8254(兼容 8253)是 Intel 公司生产的可编程定时/计数器芯片(Programmable Interval Timer, PIT),**在全部 4 套试卷中均有出现**,其中 **方波产生和计数初值计算** 是最高频题型。芯片内部包含 3 个独立的 16 位计数器,每个计数器有 6 种工作方式。
> [!tip] 考试要点
> - **计数初值计算**:`计数初值 = CLK频率 / 输出频率`
> - **方式 3(方波发生器)** 是最常考的工作方式
> - **控制字编写**:计数器选择 + 读写格式 + 工作方式 + 数制选择
> - **BCD 与二进制** 初值装入的区别
## 正文
### 1. 内部结构
```mermaid
graph TB
A["数据总线缓冲器 D0~D7"] --> B["读/写逻辑"]
B --> C["计数器 0"]
B --> D["计数器 1"]
B --> E["计数器 2"]
C --> F["CLK0, GATE0, OUT0"]
D --> G["CLK1, GATE1, OUT1"]
E --> H["CLK2, GATE2, OUT2"]
```
每个计数器有 3 条信号线:
| 信号 | 方向 | 功能 |
|------|------|------|
| **CLK** | 输入 | 时钟输入,每个下降沿使计数值减 1 |
| **GATE** | 输入 | 门控信号,控制计数的启动/暂停/触发 |
| **OUT** | 输出 | 根据工作方式输出不同波形 |
> [!question] 思考题
> 8254 的计数器是递增还是递减计数?计数值减到 0 后会怎样?
>
> 答:**递减计数**。装入初值后每来一个 CLK 下降沿计数值减 1。减到 0 后的行为取决于工作方式——方式 0 停止,方式 2/3 自动重装初值继续计数。
### 2. 端口地址
8254 占用 **4 个端口地址**:
| A1 A0 | 选中 | 说明 |
|:------:|:----:|------|
| 0 0 | 计数器 0 | 读写计数初值 |
| 0 1 | 计数器 1 | 读写计数初值 |
| 1 0 | 计数器 2 | 读写计数初值 |
| 1 1 | 控制寄存器 | 只写,用于写入控制字 |
> [!note] 每个计数器占用 1 个还是 2 个地址?
> 每个计数器只占用 **1 个端口地址**。16 位初值通过同一地址分两次写入(先低字节后高字节)。整个芯片共需 4 个端口地址。
### 3. 控制字格式
控制字写入控制寄存器(A1A0=11 的端口),格式如下:
```
D7 D6 D5 D4 D3 D2 D1 D0
[计数器] [读写格式] [工作方式] [数制]
00=计数器0 00=锁存 000=方式0 0=二进制
01=计数器1 01=仅低字节 001=方式1 1=BCD
10=计数器2 10=仅高字节 010=方式2
11=先低后高 011=方式3
100=方式4
101=方式5
```
> [!example] 控制字速算
> **要求**:计数器 0,方式 3(方波),先低后高,二进制
>
> D7D6=00(计数器 0), D5D4=11(先低后高), D3D2D1=011(方式 3), D0=0(二进制)
>
> 控制字 = `0011 0110B` = **36H**
>
> **要求**:同上但 BCD 计数 → D0=1 → 控制字 = **37H**
### 4. 六种工作方式
> [!tip] 考试重点
> 方式 2 和方式 3 的区别几乎每卷必考!
| 方式 | 名称 | 输出波形 | 触发 | 自动重装 | 典型应用 |
|:----:|------|----------|------|:--------:|----------|
| 0 | 计数结束中断 | 计数到 0 后 OUT 变高 | 软件 | 否 | 定时中断 |
| 1 | 可编程单稳态 | 触发后输出 N 个 CLK 宽度的负脉冲 | 硬件 | 否 | 单稳态触发器 |
| 2 | **频率发生器** | 每 N 个 CLK 输出 1 个 CLK 宽的负脉冲 | 软件 | 是 | **分频器** |
| 3 | **方波发生器** | 对称方波,占空比约 50% | 软件 | 是 | **方波产生** |
| 4 | 软件触发选通 | 计数到 0 后输出 1 个 CLK 宽的负脉冲 | 软件 | 否 | 软件定时选通 |
| 5 | 硬件触发选通 | 触发后计数到 0 输出 1 个负脉冲 | 硬件 | 否 | 硬件延迟脉冲 |
#### 方式 2 vs 方式 3 对比
```mermaid
graph LR
subgraph "方式 2 - 频率发生器"
A2["CLK 输入"] --> B2["计数器 N 分频"]
B2 --> C2["OUT: 周期性窄脉冲"]
end
subgraph "方式 3 - 方波发生器"
A3["CLK 输入"] --> B3["计数器 N 分频"]
B3 --> C3["OUT: 对称方波 50%"]
end
```
| 对比项 | 方式 2 | 方式 3 |
|--------|--------|--------|
| 输出波形 | 负脉冲(宽 1 个 CLK) | 对称方波 |
| 占空比 | 很小 | ≈ 50% |
| 输出频率 | CLK / N | CLK / N |
| 重装机制 | 计数到 1 时 OUT 变低,到 0 时重装 | 计数到 0 时自动重装,交替翻转 OUT |
> [!question] GATE 引脚在方式 2 和方式 3 中的作用?
> - GATE=0:暂停计数,OUT 输出高电平
> - GATE 上升沿:重新装入初值,开始计数
> - GATE=1:允许计数正常进行
### 5. 计数初值计算(核心公式)
$$
计数初值 = \frac{f_{CLK}}{f_{OUT}}
$$
> [!example] 试卷真题计算汇总
>
> | 题目来源 | CLK 频率 | 要求频率 | 计数初值 | 控制字 |
> |:--------:|:--------:|:--------:|:--------:|:------:|
> | 试题 A | 2 MHz | 2000 Hz | 1000 (03E8H) | 34H |
> | 试题 B | 1.193182 MHz | 100 Hz | 11932 (2EA4H) | 36H |
> | 试题 B | 1 MHz | 1 kHz | 1000 (03E8H) | 36H |
> | 试题 C | 1.19318 MHz | 1 kHz | 1193 (04A9H) | 36H |
> | 试题 D | 1 MHz | 1 kHz | 1000 (03E8H) | 36H |
### 6. BCD 计数 vs 二进制计数
| 项目 | 二进制(D0=0) | BCD(D0=1) |
|------|---------------|-------------|
| 计数范围 | 0000H~FFFFH (0~65535) | 0000~9999 |
| 初值装入 | 直接装入十六进制值 | 按 BCD 码装入 |
| 初值 1000 | 03E8H | 1000 (低字节=00, 高字节=10) |
> [!warning] BCD 方式装入初值的坑
> BCD 方式下初值 11932 的装入:
> - 低字节 = **32H**(低 2 位 BCD)
> - 高字节 = **11H**(高 2 位 BCD)
>
> 而不是 2EA4H!控制字也要从 36H 改为 **37H**(D0=1)。
### 7. 初始化编程模板
```asm
; 8254 初始化通用模板
; 假设端口地址为 PORT_0 ~ PORT_3
; 步骤 1:写控制字
MOV DX, PORT_3 ; 控制寄存器地址
MOV AL, 36H ; 控制字:计数器0, 方式3, 先低后高, 二进制
OUT DX, AL
; 步骤 2:写计数初值(先低后高)
MOV DX, PORT_0 ; 计数器 0 地址
MOV AX, 03E8H ; 计数初值 = 1000
OUT DX, AL ; 先写低字节 E8H
MOV AL, AH
OUT DX, AL ; 再写高字节 03H
```
> [!danger] 易错点
> 写初值时必须 **先低后高**(与控制字 D5D4=11 对应),而且低字节和高字节要 **分两次** `OUT` 到同一个端口地址。用 `OUT DX, AX` 一次写 16 位是错误的。
## 关联笔记
- [[8255A可编程并行接口]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]
- [[接口与通讯技术/试题册/index|试题册索引]]
@@ -0,0 +1,194 @@
---
tags:
- 接口与通讯技术
- 8255A
- 并行接口
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8255A 可编程并行接口
## 概述
8255A(Programmable Peripheral Interface, PPI)是 Intel 公司生产的通用可编程并行 I/O 接口芯片,**在全部 4 套试卷中均有出现**,是本课程最高频考点。它提供 3 个 8 位端口(A、B、C),支持 3 种工作方式,可通过程序灵活配置为输入/输出功能。
> [!tip] 考试要点
> - **控制字计算**:方式控制字(D7=1)和 C 口按位控制字(D7=0)的区别
> - **工作方式对比**:方式 0/1/2 的特点、联络信号
> - **端口地址推算**:已知一个端口地址推算其余端口和控制口地址
## 正文
### 1. 内部结构
8255A 内部由 **4 个功能模块** 组成:
```mermaid
graph LR
A["CPU 数据总线"] --> B["数据总线缓冲器"]
B --> C["读/写控制逻辑"]
C --> D["A 组控制"]
C --> E["B 组控制"]
D --> F["端口 A (PA0~PA7)"]
D --> G["端口 C 高 4 位 (PC4~PC7)"]
E --> H["端口 B (PB0~PB7)"]
E --> I["端口 C 低 4 位 (PC0~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 — 基本输入/输出
最简单的工作方式,无需任何联络信号(握手信号),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 变低 → 准备接收下一个数据。
#### 方式 2 — 双向总线方式
**仅端口 A 可用**,同一端口既可输入又可输出,利用端口 C 的 5 个引脚(PC3~PC7)作为联络信号。
```mermaid
graph LR
A["外设"] -- "数据 + STB/IBF" --> B["8255A 端口 A"]
B -- "数据 + OBF/ACK" --> A
B -- "INTR" --> C["CPU"]
```
### 4. 控制字格式
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**
> [!question] 关键考点
> 方式控制字和 C 口位控制字写入的是 **同一个端口地址**(控制口),如何区分?
>
> 答:通过 D7 位区分。D7=1 是方式控制字,D7=0 是位控制字。
### 5. 端口地址推算
8255A 占用 **4 个连续端口地址**,由 A1、A0 引脚选择:
| A1 A0 | 选中端口 | 相对偏移 |
|:------:|:--------:|:--------:|
| 0 0 | 端口 A | 基地址 + 0 |
| 0 1 | 端口 B | 基地址 + 2 |
| 1 0 | 端口 C | 基地址 + 4 |
| 1 1 | 控制口 | 基地址 + 6 |
> [!example] 地址推算示例
> 已知 A 口地址 = 2F0H,则:
> - B 口 = 2F0H + 2 = **2F2H**
> - C 口 = 2F0H + 4 = **2F4H**
> - 控制口 = 2F0H + 6 = **2F6H**
>
> 若 A 口地址 = 20H(小地址系统),则控制口 = **23H**。
### 6. 初始化编程模板
```asm
; 8255A 初始化通用模板
; 假设控制口地址为 PORT_CTL
MOV DX, PORT_CTL ; 控制口地址
MOV AL, 80H ; 方式控制字(按需修改)
OUT DX, AL ; 写入方式控制字
; 若需要对 C 口某位置位/复位:
MOV DX, PORT_CTL
MOV AL, 07H ; 位控制字:PC3=1
OUT DX, AL
```
## 关联笔记
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]
- [[接口与通讯技术/试题册/index|试题册索引]]
@@ -0,0 +1,231 @@
---
tags:
- 接口与通讯技术
- 8259A
- 中断控制器
- 可编程芯片
create time: 2026-06-26 23:05
---
# 8259A 中断控制器
## 概述
8259A 是 Intel 公司生产的可编程中断控制器(Programmable Interrupt Controller, PIC),**在全部 4 套试卷中均有出现**。它负责管理和控制 8086 系统中的外部中断请求,支持 8 级优先级中断,可通过级联扩展。本芯片的知识点主要集中在 **初始化命令字(ICW)编写**、**中断响应过程** 和 **优先级管理** 三个方面。
> [!tip] 考试要点
> - **ICW 写入顺序**:ICW1 → ICW2 → ICW3(可选)→ ICW4(可选)
> - **ICW2 与中断类型码**的关系
> - **中断响应时序**:两个 INTA 脉冲期间 8259A 做了什么
> - **全嵌套方式**的优先级规则
## 正文
### 1. 8259A 的核心功能
```mermaid
graph TB
A["IR0~IR7 中断请求输入"] --> B["8259A"]
B -- "INT" --> C["CPU"]
C -- "INTA" --> B
B -- "中断类型码 D0~D7" --> C
B --> D["优先级判别器"]
B --> E["中断屏蔽寄存器 IMR"]
B --> F["中断服务寄存器 ISR"]
B --> G["中断请求寄存器 IRR"]
```
| 寄存器 | 缩写 | 功能 |
|--------|------|------|
| 中断请求寄存器 | **IRR** | 记录哪些 IR 引脚有中断请求(8 位,对应 IR0~IR7) |
| 中断屏蔽寄存器 | **IMR** | 某位=1 则屏蔽对应 IR 的中断请求(通过 OCW1 设置) |
| 中断服务寄存器 | **ISR** | 记录当前正在被服务的中断(用于嵌套管理) |
| 优先级判别器 | **PR** | 从 IRR 中未被 IMR 屏蔽的请求里选出最高优先级 |
> [!question] IRR、IMR、ISR 三者如何协作?
> 1. 外设在 IRi 引脚产生中断请求 → **IRR** 对应位置 1
> 2. **IMR** 检查该位是否被屏蔽(=1 则忽略)
> 3. 未屏蔽的请求送入 **PR** 进行优先级判别
> 4. 若当前无更高优先级中断正在服务(查 **ISR**),则 8259A 向 CPU 发出 INT 信号
### 2. 初始化命令字(ICW)
8259A 有 **4 个初始化命令字**,必须按顺序写入:
```mermaid
graph LR
A["ICW1 写入偶地址"] --> B["ICW2 写入奇地址"]
B --> C{"需要级联?"}
C -- "是" --> D["ICW3 写入奇地址"]
C -- "否" --> E{"需要 ICW4?"}
D --> E
E -- "是" --> F["ICW4 写入奇地址"]
E -- "否" --> G["初始化完成"]
F --> G
```
#### ICW1(偶地址端口,A0=0)
```
D7 D6 D5 D4 D3 D2 D1 D0
[A7 A6 A5] 1 [LTIM] [SNGL] [IC4]
0=边沿 0=级联 0=不需要ICW4
1=电平 1=单片 1=需要ICW4
```
> [!info] ICW1 标志位
> D4 位 **固定为 1**,这是识别 ICW1 的标志。写入时 A0 必须为 0(偶地址端口)。
#### ICW2(奇地址端口,A0=1)
ICW2 提供 **中断类型码的高 5 位**(T7~T3),低 3 位由 8259A 自动填入 IR 编码。
```
中断类型码 = T7 T6 T5 T4 T3 [IR2 IR1 IR0]
↑ 自动填充
```
> [!example] ICW2 计算示例
> **要求**:IR0~IR7 对应中断类型码 80H~87H
>
> 80H = `1000 0000B`,高 5 位 = `10000`
>
> ICW2 = **80H**
>
> 验证:IR0 → 80H, IR1 → 81H, ..., IR7 → 87H ✓
#### ICW3(奇地址端口,仅级联时需要)
- **主片**:某位=1 表示对应 IR 引脚连接了从片
- **从片**:低 3 位表示从片的 INT 输出接到主片的哪个 IR 引脚
#### ICW4(奇地址端口,按需)
```
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 [SFNM] [BUF] [M/S] [uPM]
0=普通 0=非缓冲 0=从片 0=8080/8085
1=特殊全嵌套 1=缓冲 1=主片 1=8086/8088
```
> [!warning] 8086 系统中 ICW4 必须写
> 8086/8088 系统下,ICW4 的 D0=1(uPM=1,表示 8086 模式)是必须的。考试中常见最小初始化序列为:ICW1 → ICW2 → ICW4。
### 3. 操作命令字(OCW)
8259A 有 **3 个操作命令字**,在初始化完成后的工作过程中写入:
| OCW | 端口 | 功能 |
|-----|------|------|
| **OCW1** | 奇地址 (A0=1) | 设置中断屏蔽字(直接写入 IMR) |
| **OCW2** | 偶地址 (A0=0) | 控制中断结束方式和优先级轮换 |
| **OCW3** | 偶地址 (A0=0) | 设置特殊屏蔽、读寄存器命令 |
> [!info] EOI 命令
> OCW2 中的 **EOI(End of Interrupt)** 命令用于在中断服务程序结束时清除 ISR 中对应的位:
> - **普通 EOI**:OCW2 = 20H(非自动 EOI 模式下必须手动发送)
> - **特殊 EOI**:指定要清除的 ISR 位
### 4. 中断响应过程
```mermaid
sequenceDiagram
participant P as "外设"
participant I as "8259A"
participant C as "CPU"
P->>I: "IRi 引脚产生中断请求"
Note over I: "IRR 对应位置 1"
Note over I: "PR 判别优先级"
I->>C: "INT = 1"
C->>I: "第一个 INTA 脉冲"
Note over I: "ISR 对应位置 1, IRR 对应位清 0"
C->>I: "第二个 INTA 脉冲"
I->>C: "送出中断类型码 (D0~D7)"
Note over C: "根据类型码查向量表, 跳转 ISR"
```
> [!warning] 两个 INTA 脉冲的作用不同
> - **第一个 INTA**:8259A 内部操作(置 ISR、清 IRR),CPU 此时还未获取类型码
> - **第二个 INTA**:8259A 将中断类型码送上数据总线,CPU 读取后计算向量表地址
### 5. 中断向量表
8086 的中断向量表位于内存最低地址 **00000H~003FFH**(共 1KB),可存放 256 个中断向量。
$$
中断向量地址 = 中断类型号 \times 4
$$
每个向量占 4 字节:**低 2 字节 = IP,高 2 字节 = CS**。
```mermaid
graph LR
A["类型号 N"] -- "x4" --> B["向量地址 N*4"]
B --> C["IP 低字节"]
B --> D["IP 高字节"]
B --> E["CS 低字节"]
B --> F["CS 高字节"]
```
### 6. 优先级管理方式
| 方式 | 特点 | 适用场景 |
|------|------|----------|
| **全嵌套**(默认) | IR0 最高 → IR7 最低,固定不变 | 大多数应用 |
| **自动轮换** | 服务完的中断降为最低优先级 | 公平服务 |
| **特殊全嵌套** | 允许同级中断嵌套 | 级联系统的主片 |
> [!question] 全嵌套方式下,IRQ5 正在服务,哪些中断可以打断它?
> 答:只有优先级更高的 IRQ0~IRQ4 可以打断。IRQ6 和 IRQ7 必须等待 IRQ5 服务完成后才能获得响应。
### 7. 级联扩展
| 配置 | 中断级数 | 说明 |
|------|:--------:|------|
| 单片 8259A | 8 级 | IR0~IR7 |
| 一主一从级联 | 15 级 | 从片占用主片 1 个 IR 端口(8+8-1=15) |
### 8. 典型初始化程序
```asm
; 8259A 初始化示例
; 端口地址:20H(偶地址,A0=0),21H(奇地址,A0=1)
; 中断类型码:80H~87H
; ICW1:边沿触发,单片,需要 ICW4
MOV AL, 13H
OUT 20H, AL
; ICW2:中断类型码基址 = 80H
MOV AL, 80H
OUT 21H, AL
; ICW4:8086 模式,非自动 EOI
MOV AL, 03H
OUT 21H, AL
; OCW1:设置中断屏蔽字(可选)
MOV AL, 00H ; 允许所有中断
OUT 21H, AL
```
> [!example] 中断服务程序模板
> ```asm
> INT_ISR PROC FAR
> PUSH AX ; 保护现场
> PUSH BX
> ; ... 中断处理逻辑 ...
> MOV AL, 20H ; 普通 EOI 命令
> OUT 20H, AL ; 发送到 8259A
> POP BX ; 恢复现场
> POP AX
> IRET ; 中断返回
> INT_ISR ENDP
> ```
## 关联笔记
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8251A串行通信接口]]
- [[接口与通讯技术/试题册/index|试题册索引]]
+4 -4
View File
@@ -48,7 +48,7 @@ quadrantChart
```
## 关联笔记
- [[接口与通讯技术/8255A可编程并行接口]]
- [[接口与通讯技术/8254定时计数器]]
- [[接口与通讯技术/8259A中断控制器]]
- [[接口与通讯技术/8251A串行通信接口]]
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]
+4 -4
View File
@@ -384,7 +384,7 @@ create time: 2026-06-26 22:20
---
## 关联笔记
- [[接口与通讯技术/8255A可编程并行接口]]
- [[接口与通讯技术/8254定时计数器]]
- [[接口与通讯技术/8259A中断控制器]]
- [[接口与通讯技术/8251A串行通信接口]]
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]
+4 -4
View File
@@ -375,8 +375,8 @@ create time: 2026-06-26 22:20
---
## 关联笔记
- [[接口与通讯技术/8255A可编程并行接口]]
- [[接口与通讯技术/8254定时计数器]]
- [[接口与通讯技术/8259A中断控制器]]
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[接口与通讯技术/DMA控制器8237A]]
- [[接口与通讯技术/8251A串行通信接口]]
- [[8251A串行通信接口]]
+3 -3
View File
@@ -568,6 +568,6 @@ create time: 2026-06-26 22:20
---
## 关联笔记
- [[接口与通讯技术/8255A可编程并行接口]]
- [[接口与通讯技术/8254定时计数器]]
- [[接口与通讯技术/8259A中断控制器]]
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
+4 -4
View File
@@ -425,7 +425,7 @@ create time: 2026-06-26 22:20
> 解析:计数初值 = 1MHz / 1kHz = 1000 = 03E8H。控制字 36H 各位含义:D7D6=00 选择计数器 0,D5D4=11 先低后高读写,D3D2=011 方式 3(方波发生器),D0=0 二进制计数。先写低字节(E8H),再写高字节(03H)到计数器 0 的端口 20H。
## 关联笔记
- [[接口与通讯技术/8255A可编程并行接口]]
- [[接口与通讯技术/8254定时计数器]]
- [[接口与通讯技术/8259A中断控制器]]
- [[接口与通讯技术/8251A串行通信接口]]
- [[8255A可编程并行接口]]
- [[8254定时计数器]]
- [[8259A中断控制器]]
- [[8251A串行通信接口]]