通用异步收发传输器(UART)
12.1 概述
在没有任何输出信号(如视频信号)或输入信号(如键盘)的情况下,计算机需要一种与用户或其他计算机通信的方式。正如我们刚刚看到的,I/O 就是为此而设计的。然而,我们还需要一种协议来描述这些实体之间的通信方式。
最常用的通信协议是通用异步收发传输器,即 UART。让我们看看它在我们的情况中是如何工作的。
12.2 硬件实现
在 Z80 PIO 章节中,我们看到系统端口的两个 I/O 专用于 UART,分别是:
- TX,输出端,由 Zeal 8-bit Computer 驱动。它用于输出一个字节(通常是一个 ASCII 字符),供另一端(可能运行在主机上)的终端程序处理或显示。
- RX,输入端,由另一端的计算机驱动,该计算机向 Zeal 8-bit Computer 发送字节。当用户在终端中键入字符时,这些字符将通过此线路转发。
通常,UART 协议可能包含更多线路,如 $\overline{CTS}$ 或 $\overline{RTS}$,但我们故意省略了它们,因为 Zeal 8-bit Computer 没有这些线路。
RX 和 TX 线路使用相同的协议但相互独立,无论 RX 状态如何,我们都可以在 TX 线上发送字节,反之亦然。然而,在 Zeal 8-bit Computer 上,我们没有专用的 UART 集成电路,而是通过软件模拟该协议,这意味着软件必须手动设置 TX 引脚电平或适时读取 RX 线电平,以生成或确定要发送或接收的字节。
这种实现方式存在若干缺点,比如比使用专用芯片慢,或者无法异步接收字节,但选择这种实现方式有以下几个原因:
- Zeal 8-bit Computer 的主要目标是配合视频卡使用,视频卡将作为主显示器,是向用户显示文本或图形的主要方式。
- 接收用户输入的方式是使用 PS/2 键盘端口,它可以触发异步中断。因此,拥有同步 UART RX 信号并不关键。
- 在主板上添加 UART 芯片将需要 PCB 上更多的空间,并导致更复杂的布线。
总的来说,UART 应作为一个次要功能,主要用于与其他计算机之间同步发送或接收大量数据。
以下小图展示了如何设置 UART:
12.3 协议描述
UART 协议将一次传输描述如下:
- 传输线(TX 和 RX)在空闲时为高电平。
- 要发起一次传输,会发送一个起始位,这意味着线路被设置为低电平,持续时间为 $τ$。
- 在线路上发送字节的每一位,其中 0 用低逻辑电平表示,1 用高逻辑电平表示。最低有效位先发送。每一位持续 $τ$。虽然大多数情况下一个字节由 8 位组成,但 UART 协议规定它可以在 5 到 9 位之间变化。
- 然后是一个可选的奇偶校验位,同样持续时间为 $τ$。
- 最后,发送一个或两个停止位,这意味着线路被设置为高电平,分别持续一个或两个 $τ$ 的时间。
我们可以注意到没有时钟信号,这意味着发送方和接收方必须事先就数据位数、停止位数以及每次传输是否包含奇偶校验位达成一致。
当然,最后一个主要参数是 $τ$,即每个比特持续的时间。对于 UART,这由波特率决定,它表示每秒发送的比特数。
例如,如果选择的波特率为 115200,每个比特将持续 $\frac{1}{115200} * 1000000 = 8.68 \mu s$,因此 $τ=8.68 \mu s$
下图总结了该协议:
⚠️ 警告
在 Zeal 8-bit Computer 上,高逻辑电平为 5V,这也适用于 UART。在将其连接到其他设备之前,请确保该设备支持 5V I/O。如果该设备支持 5V I/O 但产生 3.3V 逻辑电平,则完全兼容。任何高于或等于 2V 的电压都将被 UART RX 线后面的 Z80 PIO 解释为高逻辑电平。
12.4 限制
由于 UART 是在 Zeal 8-bit Computer 上通过软件模拟的,实际上,TX 的极限波特率为 115200,RX 的极限为 57600。
在 RX 线上,理论上也可以达到 115200,但当发送大量数据时,程序可能没有足够的时间处理刚刚接收到的数据并准备接收下一个数据,因此合理的限制是 57600。
关于如何在不同波特率下生成符合规范的 TX 和 RX 信号的开源编程示例,可以在 Zeal 8-bit Bootloader 源代码 中找到。