跳转至

Basic I/O Interface⚓︎

4596 个字 预计阅读时间 23 分钟

Intro to I/O Interface⚓︎

Hardware Interface⚓︎

硬件接口建立起不同设备之间的连接和通信,实现计算机和外设的协同工作。

硬件接口提供了以下解决方案:

  • 信号匹配 (signal matching) -> 信号转换 (signal conversion)
  • 信号驱动 (signal driving) -> 信号增强 (signal boost)
  • 速度匹配 (speed matching) -> 数据锁存器和缓冲区 (data latch and buffer)
  • 时序匹配 (timing matching) -> 时序控制 (timing control)
  • 总线隔离 (bus isolation) -> 三态缓冲器 (three-state buffer)
  • 格式匹配 (formating matching) -> 协议转换 (protocol translation)

硬件接口的类型:

  • 按信息流方向分类:输入 / 输出接口
  • 按信号类型分类:模拟 (analog)/ 数字 (digital) 接口
  • 按数据传输类型分类:串行 (serial)/ 并行 (parallel) 接口

硬件接口的结构:一个 I/O 单元包含以下块:

  • / 写控制逻辑
  • 数据总线缓冲区 (data bus buffer)
  • 端口寄存器 (port registers)(比如端口 A,端口 B 等)
  • 控制和状态寄存器 (control and status registers)

A Few Key Points about I/O Interface⚓︎

  • 如何将 I/O 设备和 CPU 连接
    • 输出接口:锁存器
    • 输入接口:三态缓冲器
  • 如何为 I/O 设备提供地址空间
    • 隔离 I/O
    • 内存映射 I/O
  • 如何执行 I/O 端口解码
    • 包含以下信号:内存地址、#BHE、#BLE、#IORC、#IOWC
  • 如何让处理器和 I/O 设备同步
    • 对于始终开启的 (always-on) 设备采用无条件传输(unconditional transfer)
    • 选通(strobing)
    • 握手(handshaking)和轮询(polling)
    • 中断驱动的(interrupt-based) I/O
    • 基于通道的(channel-based) I/O(比如 DMA

Isolated and Memory-Mapped I/O⚓︎

下面介绍两种不同的 I/O 接口方法

  • 隔离 I/O(isolated I/O):使用 INOUT 传输,数据在微处理器的累加器或内存与 I/O 设备之间
  • 内存映射 I/O(memory-mapped I/O):任何引用内存的指令都可以完成传输

PC 使用隔离 I/O 而不是内存映射 I/O

Isolated I/O⚓︎

  • 在基于 Intel 的系统中,最常用的 I/O 传输技术是隔离 I/O
  • 隔离(isolated) 描述了 I/O 位置如何通过单独的 I/O 地址空间中从内存中隔离
  • 隔离 I/O 设备的地址,称为端口(ports),与内存分离
优点

端口是分开的,用户可以在不把任何内存空间用于 I/O 设备的情况下,将内存扩展到其最大容量。

缺点
  • I/O 与微处理器之间传输的数据必须通过 ININSOUTOUTS 指令访问
  • 需要为 I/O 空间开发单独的控制信号(使用 \(\text{M}/\overline{\text{IO}}, \text{W}/\overline{\text{R}}\),表示 I/O 读(\(\overline{\text{IORC}}\))或 I/O 写(\(\overline{\text{IOWC}}\))操作
  • I/O 操作速度慢,因为需要使用专门的 I/O 指令,同时让编程更加复杂

Memory-Mapped I/O⚓︎

  • 内存映射 I/O 不使用 ININSOUTOUTS 指令
  • 它使用任何在微处理器和内存之间传输数据的指令
优点
  • 更快的 I/O 操作:允许 CPU 以与访问内存相同的速度访问 I/O 设备(其实访问内存速度也并不快啊
  • 简化编程:可以使用相同的指令来访问内存和 I/O 设备
缺点
  • 有限的 I/O 地址空间:这种设计限制了 I/O 地址空间,因为 I/O 设备共享与内存相同的地址空间。这意味着可能没有足够的地址空间来寻址所有 I/O 设备
  • 响应时间较慢:若 I/O 设备响应缓慢,可能会延迟 CPU 对内存的访问,从而导致整体的系统性能变慢
例子(隔离 I/O vs 内存映射 I/O

Personal Computer I/O Map⚓︎

PC 使用部分 I/O 映射,用于一些专用的功能 – 端口 0000H-03FFH 之间的 I/O 空间保留给系统0400HFFFFH 端口可供用户使用

Logic ICs⚓︎

逻辑接口电路 (logical interfacing circuitry) 的分类:

  • TTL(晶体管 - 晶体管逻辑 (transistor-transistor logic))逻辑

    • 一种双极性逻辑集成电路,于早期引入
    • 更高的电流驱动能力和更高的速度(5-10 ns)
    • 消耗更多功率
      • 传统上使用 5V 电源供电,而 TTL 兼容的 CMOS 设备只使用 3.3V
    • TTL 信号必须符合以下逻辑 1 和逻辑 0 的规范:

  • CMOS 逻辑

    • 消耗的功率比 TTLs
    • 刚发明出来的时候速度较慢(25-50ns)
    • 但现在的速度比 TTL
    • 电源供电选择多样,比如 5V、3.3V、1.8V
    • CMOS 信号必须根据供电电压(VCC)满足特定的电压水平,以实现逻辑 1 和逻辑 0 ,以下是通用规格:

下面总结了这两种逻辑的输入输出规范:

  • TTL 在现代设备中很少见:TTL 主要存在于旧设备中(例如,82C55,RS-232。大多数现代接口(例如,USB,PCIe)由于功耗较高和可扩展性有限,已经远离了 TTL 信号
  • CMOS 在新设计中占主导地位:由于效率高和可扩展性强,低压 CMOS 兼容性成为现代接口的标准
  • 用于旧设备的解码器:当需要 TTL 兼容性时,使用电平转换器或电压转换器来连接 TTL CMOS 逻辑电平

Input Devices⚓︎

关于输入设备接口的考虑因素:

  • 当连接到微处理器时,输入设备应与 TTL/CMOS 兼容
  • 应减少或消除输入设备的噪声(noise)

例如,对于基于开关的设备 (switch-based devices)

  • 它们不是 TTL/CMOS 兼容的输入设备,所以应进行一些适配以使其成为 TTL/CMOS- 开关
  • 由于开关抖动 (bounce),应应用一些条件以去抖动机械接触

右图展示了一个正确连接的切换开关,作为输入设备。

  • 开关关闭时接地,产生一个有效的逻辑 0 电平
  • 使用一个上拉电阻 (pull-up resistor),确保当开关打开时,输出信号是逻辑 1

    • 上拉电阻的标准值范围在 1KΩ 10KΩ 之间
  • 机械开关在按下或释放时总会产生噪声

  • 有几种方法可以防止以上抖动问题:

    • 带触发器 (flip-flop) 的双掷开关 (double-throw switch)(图 (a)
    • 带非门的双掷开关(图 (b)

    • 低通滤波器 (low-pass filter) 和施密特触发器 (Schmitt trigger)

    • 多级移位寄存器 (multiple stage shift register) 采样

      • 开关通常会在 5-10ms 内抖动
      • 连接一个 100Hz 的时钟,它将每 10ms 采样一次信号
      • 当所有采样值都为高时,设置 SR 触发器,当值为低时重置

    • 软件采样

Output Devices⚓︎

  • 输出设备比输入设备种类更多,但许多设备都以统一的方式连接。
  • 连接输出设备需要匹配设备和微处理器的电压和电流关系
  • 接口元件的微处理器输出电压与 TTL 兼容

    • 逻辑 0 = 0.0V-0.4V
    • 逻辑 1 = 2.4V-5.0V
  • 处理器和许多接口组件的电流小于标准 TTL

    • 逻辑 0 = 0.0-2.0mA
    • 逻辑 1 = 0.0-400μA
  • 下图展示了如何通过两种方法提供足够的电流(10mA)来点亮 LED

    • (a) 使用了一个晶体管驱动器

      • 2N2222 是一款性能良好、价格低廉的通用开关晶体管,其最小增益为 100 – 集电极电流为 10mA,因此基极电流将是集电极电流的 1/100,即 0.1mA
      • 为了确定基极电流 - 限流电阻,使用 0.1mA 的基极电流并在基极电流–限流电阻上产生 1.7V 的电压降
    • (b) 使用了一个 TTL 反相器(inverter)

      • 它在逻辑 0 级别下提供高达 16mA 的电流,足以驱动一个标准 LED
    • TTL 输入信号的最小值为 2.4V

    • 发射极 - 基极结的压降为 0.7V
    • 电阻上的压降为 1.7V
    • 电阻的值为 1.7V / 0.1mA = 17KΩ
    • 由于 17K 不是标准值,选择了一个 18K 电阻
  • 假设我们需要将一个 12 V 直流 1A 电机连接到微处理器。

    • 不能使用 TTL 反相器:

      • 12V 信号会烧毁反相器
      • 电流远超过 16mA 反相器的最大值
    • 也不能使用 2N2222 晶体管:

      • 最大电流为 250mA-500mA(取决于选择的封装样式)
    • 解决方案是使用达林顿对(Darlington-pair),例如 TIP120

      • 成本 25 美分,可以处理 4A 电流
    • 下图展示了连接到具有最小电流增益 7000 和最大电流 4A 的达林顿对电机

      • 达林顿对必须使用散热片(heat sink),因为电流量较大
      • 二极管必须存在,以防止达林顿对被电感反冲(inductive kickback) 摧毁
    • 基极电阻的值与 LED 驱动器中使用的值完全相同

    • 通过电阻的电流为 1.0A / 7000 ≈ 0.143mA
    • 由于两个二极管压降(基极 / 发射极结,电压降为 0.9V
    • 基极电阻的值为 0.9V / 0.143mA = 6.29KΩ

Basic Input and Output Interfaces⚓︎

  • IN:将数据从 I/O 设备移动到微处理器中
  • OUT:将数据从微处理器移动到 I/O 设备中
  • 基本输入设备是一组连接到数据总线上的三态缓冲器
  • 基本输出设备是一组数据锁存器,用于存储来自数据总线上的值

The Basic Input Interface⚓︎

  • 三态缓冲器用于构建下图所示的 8 位输入端口

  • 外部 TTL 信号连接到缓冲器的输入端,缓冲器输出连接到数据总线

  • 当选择信号变为逻辑 0 时,该电路允许处理器读取连接到数据总线任何 8 位部分的八个开关的内容
  • 当执行 IN 指令时,开关的内容复制到 AL 寄存器
  • 这个基本输入电路是必需的,每次输入数据与微处理器接口时都必须出现
  • 有时作为电路的独立部分出现,如上图所示;也可以集成在可编程 I/O 设备中
  • 16 位或 32 位数据也可以用于接口,但不如 8 位数据常见

The Basic Output Interface⚓︎

  • 通常必须为某些外部设备保存从处理器处接收到的数据

    • 锁存器或触发器通常集成在 I/O 设备中
  • 下图显示了八个发光二极管(LED)如何通过一组八个数据锁存器连接到处理器

    • 锁存器存储微处理器从数据总线输出的数字,以便 LED 可以用任何 8 位二进制数点亮
  • 锁存器需要保持数据,因为当处理器执行 OUT 操作时,数据只在数据总线上存在不到 1.0μs,因此观察者永远不会看到 LED 灯点亮

  • 当执行 OUT 时,ALAXEAX 中的数据通过数据总线传输到锁存器,并且 \(\overline{\text{SEL}}\) 信号激活,将数据捕获到触发器,数据保持到下一个 OUT
  • 当执行输出指令时,AL 寄存器中的数据出现在 LED 灯上

Asynchronous Data Transfer⚓︎

  • CPU I/O 设备可能具有不同的时钟,这些时钟彼此不同步,即这些单元相对于彼此异步(asynchronous)
  • 异步数据传输的方法:
    • 选通(strobing)(1 个控制信号)
    • 握手(handshaking)(2 个控制信号)

Strobing⚓︎

  • 选通信号(strobe) 是一种同步信号,用于指示数据传输的开始和结束
  • 可以被源单元或目标单元激活,因此使用选通信号进行数据传输有两种方法:

    • 源启动传输(source-initiated transfer)

      • 源端首先将数据放置在数据总线上,然后改变选通信号从 0 变为 1
      • 目标端将传输设置到寄存器上
      • 源端随后将选通信号从 1 变为 0
      • 源端从数据总线上移除数据
    • 目标启动传输(destination-initiated transfer)

      • 目标端将选通信号从 0 变为 1
      • 源端将数据放置在数据总线上
      • 目标端在寄存器中捕获数据,并将选通信号从 1 变为 0
      • 源端从数据总线上移除数据
  • 数据传输的选通方法虽然简单,但存在以下几个缺点:

    • 数据必须是有效的,并且必须在总线上保持足够长的时间,以便目标端能够接受它
    • 没有迹象表明是否数据实际上被目标端捕获
    • 对于具有各种速度的多个单元,传输由最慢的单元决定
  • 解决方案:引入一个提供对启动传输的单元的回复(reply) 的第二控制信号(即下面马上介绍的握手方法)

Handshaking⚓︎

  • 双信号握手(handshaking) 方法或轮询数据传输的基本原理如下:

    • 发起单位的一条控制线(请求(request))用于请求其他单位的响应
    • 来自其他单位的第二条控制线(回复(response))用于向发起单位回复响应正在发生
  • 通过这种方式,每个单位都向其他单位告知其状态,从而使数据通过总线有序传输

  • 源启动传输中:

    • 源端首先将数据放置在数据总线上,然后启用请求
    • 目标端设置传输并激活响应
    • 源端移除数据并重置请求
    • 目标端重置响应
  • 目标启动传输中:

    • 目标端通过启用请求来启动传输
    • 源端将数据放置在数据总线上,然后激活回复
    • 目标端捕获数据并重置请求
    • 源端移除数据然后重置回复
例子

以下示例展示了从计算机到打印机通过数据连接(\(\text{D}_7-\text{D}_0\))进行数据传输的步骤。

  • ASCII 数据放置在 \(\text{D}_7-\text{D}_0\),然后对 \(\overline{\text{STB}}\) 连接应用脉冲
  • \(\overline{\text{STB}}\) 是用于向打印机发送数据的时钟脉冲
  • \(\text{BUSY}\) 表示打印机处于忙碌状态
  • 脉冲信号(请求)将数据发送到打印机,以便打印
  • 当打印机接收数据时,它在 \(\text{BUSY}\) 引脚上放置逻辑 1回复,表示正在打印数据
  • 软件轮询或测试 \(\text{BUSY}\) 引脚以决定打印机是否忙碌
    • 如果打印机忙碌,处理器等待
    • 如果不忙碌,下一个 ASCII 字符发送到打印机

I/O Port Address Decoding⚓︎

  • I/O 设备选择:

    • 解码地址,以生成与在总线上的设备地址对应的唯一信号
    • 当设备地址信号和控制信号(\(\overline{\text{IORC}}, \overline{\text{IOWC}}\))都为低电平时,生成设备选择信号
    • 使用设备选择信号激活输入输出接口技术 (input output interfacing tachniques)
  • 接口 I/O 设备包括

    • I/O 端口的选择(selection),即 I/O 端口地址解码
    • I/O 端口和微处理器之间传输数据
  • 对于 I/O 端口地址解码

    • 内存映射 I/O:使用与内存相同的地址进行解码
    • 隔离 I/O:将较少的地址引脚连接到解码器,并生成单独的控制信号(例如,I/O \(\overline{\text{IORC}}\) I/O \(\overline{\text{IOWC}}\))以激活 I/O 设备

Decoding 8-Bit I/O Port Addresses⚓︎

  • 固定 I/O 指令使用一个 8 I/O 端口地址,在 \(A_{15}–A_0\) 上为 0000H00FFH,但通常只用 \(A_7–A_0\)
  • DX 寄存器也可以寻址 I/O 端口 00HFFH
  • 如果地址被解码为 8 位地址,我们永远不能包含使用 16 位地址的 I/O 设备,因为 PC 永远不会使用或解码 8 位地址
  • 下图展示了一个 74ALS138 解码器,它能解码 8 I/O 端口F0H -F7H

    – 这和内存地址解码器相同,除了只将地址位 \(A_7-A_0\) 连接到解码器的输入端

  • 下图展示了 PLD 版本,使用 GAL22V10(一种低成本设备)作为此解码器

    • PLD 是一种更好的解码器电路,因为集成电路的数量已减少到一个设备

Decoding 16-Bit I/O Port Addresses⚓︎

  • PC 系统通常使用 16 I/O 地址,但在嵌入式系统中很少见
  • 解码 8 位和 16 I/O 地址之间的区别是:必须解码额外的 8 个地址线(\(A_{15}–A_8\)
  • 下图展示了包含 PLD 和用于解码 I/O 端口 EFF8HEFFFH 4 输入 NAND 门电路

    • PLD I/O 端口生成地址选通信号

8- and 16-Bit Wide I/O Ports⚓︎

  • I/O 空间按(banks) 组织(就像内存系统一样)以支持单字节传输未对齐的内存访问,例如:

    • in AL, 40H, in AL, 41H
    • out 40HAL, out 41HAL
  • 在这样的微处理器上,I/O 系统包含两个 8 位内存库

  • 类似于内存库选择

    • 任何 8 I/O 请求都需要单独的写选通信号(\(\overline{\text{BHE}}, \overline{\text{BLE}}\)
    • 请求不需要
  • 传输到 8 I/O 设备的数据位于 16 位处理器(如 80386SX)的一个 I/O 库中

  • 下图展示了用于像 80386SX 16 位系统的一个单独的 I/O

  • I/O 读取不需要单独的选通信号

    • 就像内存一样,处理器只读取它期望的字节,忽略其他字节
    • I/O 设备对读取操作响应错误时,读取可能会引起问题
例子

下图所示的系统包含了两个不同的 8 位输出设备(出现在不同的 I/O 库中,分别位于 40H41H

  • 因此生成独立的 I/O 写信号以时钟驱动一对捕获端口数据的锁存器

下图展示了一个 16 位设备连接到 64H65H 8 位地址上。

  • PLD 解码器没有 \(\overline{\text{BLE}}\)\(A_0\))和 \(\overline{\text{BHE}}\) 地址位连接,因为信号不适用于 16 位宽的设备
  • PLD 的程序展示了如何生成用于作为输入设备的三态缓冲器(74HCT244)的使能信号

32-Bit-Wide I/O Ports⚓︎

  • 这种宽度的端口最终可能会普及,因为计算机系统的总线在更新
  • EISA 系统总线、VESA 局部和当前 PCI 总线支持 32 I/O
  • 下图展示了 80386DX-80486DX 微处理器的 32 位输入端口

    • 电路使用单个 PLD 来解码 I/O 端口,并使用四个 74HCT244 缓冲器将 I/O 数据连接到数据总线
    • 通过此接口解码的 I/O 端口是 8 位端口 70H73H
    • 通过写入访问此端口时,使用地址 70H 对于 32 位输入至关重要,比如指令 in EAX, 70H

The Programmable Peripheral⚓︎

8254 Programmable Interval Timer⚓︎

16550 Programmable Communications Interface⚓︎

ADC & DAC Converters⚓︎

评论区

如果大家有什么问题或想法,欢迎在下方留言~