串行编程/典型 RS232 硬件配置
串行编程: 介绍和 OSI 网络模型 -- RS-232 接线和连接 -- 典型 RS232 硬件配置 -- 8250 UART -- DOS -- MAX232 驱动器/接收器系列 -- Windows 中的 TAPI 通信 -- Linux 和 Unix -- Java -- Hayes 兼容调制解调器和 AT 命令 -- 通用串行总线 (USB) -- 形成数据包 -- 错误校正方法 -- 双向通信 -- 数据包恢复方法 -- 串行数据网络 -- 实际应用开发 -- IP 通过串行连接
本页面概述了各种计算机和设备中常见的串行 RS232 硬件配置。它应该作为一些串行硬件直接编程的指南和介绍。
提供的資訊具有通用性,因為某些設備或計算機中找到的實際串行硬件可能有所不同。如今,硬件通常集成在一个芯片中,甚至具有许多其他功能,例如并行端口,与串行通信无关。然而,本模块提供了关于哪些逻辑或物理组件执行什么以及串行硬件的实际编程发生位置的良好概述。
下图概述了相关组件及其连接方式
RS232 +-----------+ +-----------+ +-----------+ +-----------+ Interface | Line | | | | Interface | | | -----------+ Driver / +---+ UART +---+ Logic +---+ CPU | | Receiver | | | | | | | +-----------+ +-----+-----+ +-----+-----+ +-----------+ | | | | +-----+-----+ | | Baud Rate | | | Generator +---------+ | | +-----------+
我们将依次讨论这些组件及其用途。
RS-232 通信使用高达 ±15V 的电压(一些早期规格甚至使用 ±25V)。它使用反向逻辑(高/真/1 是负电压,低/假/0 是正电压)。这些电压对于现代(甚至更旧的)计算机逻辑来说太高了。因此,RS-232 接口通常包含特殊的硬件,即所谓的线路驱动器和线路接收器。
线路驱动器负责将典型的计算机电压逻辑转换为 RS-232 线路上使用的较高电压,并反转逻辑。这在计算机硬件传输串行数据时使用。电压输出通常是连续短路安全的,因为这是 RS-232 标准的要求。
线路接收器负责执行线路驱动器的反向操作。它将传入的 RS-232 信号转换为对计算机逻辑安全的电压,当然也反转逻辑。
实际上,通常使用不止一个线路驱动器和接收器,因为 RS-232 电缆中的每个传入 RS-232 信号都需要它自己的接收器,每个传出 RS-232 信号都需要它自己的驱动器。但是,通常多个驱动器/接收器组合在一个芯片中。该芯片本身还保护计算机逻辑免受可能发生在串行线上的尖峰电压。一些线路驱动器/接收器芯片甚至在芯片上产生必要的 RS-232 电压,而另一些则需要外部电源来提供这些电压。
线路驱动器/接收器通常不可编程。它们被硬连线到逻辑中,因此对于程序员来说无关紧要。
另请参阅
- 模块 MAX232 驱动器/接收器系列,了解业余电子产品中流行的驱动器/接收器示例。
- 模块 RS-232 接线和连接
UART(通用异步接收器/发送器)是串行硬件的核心。它是一个芯片或芯片的一部分,其目的是在并行数据和串行数据之间转换。RS-232 UART 通常还会在传输时添加必要的起始/停止位和奇偶校验位,并在接收时解码这些信息。
UART 通常完全在计算机逻辑电压下工作。其串行数据输入/输出电压是计算机逻辑电压,而不是串行线路电压。它们将实际线路接口留给特定的线路驱动器/接收器。该线路驱动器/接收器不一定需要是 RS-232 线路驱动器/接收器,也可以是 RS-422 差分驱动器/接收器。这是 UART 被称为通用的原因,以及波特率、奇偶校验、停止位数量、数据位数量可编程也是原因。如果 UART 和线路驱动器/接收器都放置在同一个芯片中,它们之间的区别就会变得模糊。此类芯片通常也以“UART”的标签出售。
UART 被称为异步,因为它们不使用特殊的时钟信号与远程端同步。相反,它们使用起始/停止位来识别串行流中的数据位。
由于 UART,其余硬件以及软件应用程序都可以处理普通字节来保存通信数据。UART 的工作是在发送时将一个字节切分成一系列串行位,并在接收时将一系列位组装成一个字节。UART 通常包含 8 位宽的接收器和发送器缓冲区。如果使用 7 位传输等,则可能不会使用所有位。接收到的串行数据以并行方式提供给接收器缓冲区,要发送的数据以并行方式写入发送器缓冲区。根据 UART 的不同,缓冲区可能只有一字节深,也可能只有几字节深(在 15 或 16 字节范围内)。缓冲区越浅,与 CPU 的通信就越需要精确。例如,如果接收器缓冲区只有一字节深,并且数据没有被及时获取,则下一个接收到的数据可能会覆盖接收器缓冲区中先前接收到的数据,并且先前接收到的数据将丢失。
由于串行接口上的时序很重要,因此 UART 通常连接到波特率发生器,可以是 UART 芯片中的内部波特率发生器,也可以是外部波特率发生器。
USART(通用同步/异步接收器/发送器)是 UART 的一个版本,它也可以同步通信。许多现代 IC 具有此功能。但是,由于 RS232 异步工作,因此 USART 的同步功能不用于串行通信。根据 USART 的特定类型,同步功能要么在启动时关闭,要么需要关闭。一旦关闭,USART 在进行 RS232 通信时就是 UART。
波特率发生器是一个振荡器。它提供一个频率信号,用于控制串行接口的时序。由于不同的线路速度需要不同的时序,因此波特率生成需要灵活。
实现灵活的波特率生成一般有两种方法:波特率生成器本身可编程,可以生成所需的各种频率;或者 UART 有可编程的分频器或倍频器,将波特率生成器的频率转换为所需的频率。观察者可能已经注意到,典型的波特率(300bps、600bps、1200bps、2400bps、9600bps(4 x 2400bps)等)之间存在固定关系。这简化了使用分频器或倍频器来生成所需时序的过程。
根据 UART 的具体情况,波特率生成器可能需要一些外部组件,也可能直接集成到 UART 芯片中。从外部来看,对波特率生成进行编程改变是控制串行连接速度的方法。在对波特率进行编程时,通常不直接提供所需的波特率“明文”,而是需要提供一些分频器或系数。要提供正确的分频器或系数,需要了解所用波特率生成器的基本频率。
RS-232 通信是异步的。因此,发射机和接收机之间没有显式的方法,也没有共享的时钟信号来进行同步。相反,它们通过起始位进行同步,并进一步假设一定的比特长度。比特长度是波特率的直接函数。例如,RS-232 上的 9600 波特意味着每秒传输 9600 个比特。因此,每个比特的长度为 1/9600 秒。为了确保发射机和接收机假设相同的比特长度,它们需要使用相同的波特率。并且通信双方的波特率需要精确到一定程度。否则数据传输将会失败。当双方的波特率没有很好地对齐时,常见的错误包括帧错误、接收错误或丢失比特。
波特率生成器,因为它生成发送和接收数据的时钟频率,负责提供所需的波特率精度。作为经验法则,通常情况下,波特率的总偏差在最坏情况下不应超过 +/- 4%。如果将这个“误差预算”平均分配到两边,这意味着每边的波特率需要保持在标称值的 +/- 2% 以内。实际上,应该避免这种最坏情况,并将波特率至少保持在每边的 +/- 1% 以内。
通常使用晶体振荡器来构建波特率生成器,该生成器具有适用于 RS-232 的初始精度、温度漂移和长期漂移。也就是说,波特率生成器基于一个振荡器,该振荡器反过来使用石英晶体作为参考。更简单的振荡器,例如 RC 振荡器,通常不够好。
通常,所有晶体振荡器电子设备都集成在波特率生成器 IC 中。如果使用具有集成波特率生成器的 UART,该 UART 通常包含这些电子设备。通常只需要添加石英晶体。
为了实现常见的波特率,石英晶体的频率值需要具有某些“魔法”值。乍一看,这些值似乎相当奇怪。但是,它们通常是 300(通常是支持的最低波特率)或 25(对于 25、50、75、150 的极低波特率)和二的幂的倍数。使用二的幂是因为将频率除以二的幂很容易,从而使可配置或可编程波特率生成器成为可能。
例如,将相当奇怪的晶体频率 4.915200 MHz 除以 256(二的幂),得到 19200 Hz 的不错值。频率为 4.915200 MHz 的晶体被称为波特率晶体或魔法晶体。下表列出了常见的波特率晶体频率。
- 1.8432 MHz、3.6864 MHz、4.9152 MHz、5.5296 MHz、6.1440 MHz、7.3728 MHz、9.8304 MHz
- 11.0592 MHz、12.2880 MHz、12.9024 MHz、14.7456 MHz、16.5888 MHz、18.4320 MHz、19.6608 MHz
- 20.2752 MHz、22.1184 MHz、23.9616 MHz、25.8048 MHz、27.6480 MHz、29.4912 MHz
- 31.3344 MHz、33.1776 MHz、35.0208 MHz、36.8640 MHz
使用哪个晶体频率取决于所用的波特率生成器/UART。应参考波特率生成器/UART 的数据手册以获取详细信息。
UART 和波特率生成器只是芯片,或者可以是更大芯片的组件。为了简化讨论,我们假设它们是一个芯片。该芯片通常有一堆引脚,这些引脚需要以某种方式由 CPU 写入或读取。因此,需要一些方法让 CPU 寻址该芯片以与其通信。还需要一些方法让芯片在某些情况下发出声音。
接口逻辑的任务是提供这种连接。逻辑因系统架构的不同而异。一种常见的技术是将 UART 的发送和接收缓冲区映射到 CPU 的内存地址空间中。这样一来,它们对于 CPU 来说就像普通的内存一样。另一种方法是将这些缓冲区连接到某些 CPU 特定的 I/O 端口。除了发送和接收缓冲区外,CPU 还必须能够访问 UART 的控制线、波特率、奇偶校验和字符大小编程接口。
由于 UART 不能缓冲无限量的传入数据(有些只能在接收缓冲区中缓冲一个字节),CPU(或其他硬件)需要“足够快”地从 UART 读取数据。CPU 可以连续轮询 UART 以检查是否有新数据可用,或者 UART 可以通知何时有新数据准备好。这种通知通常通过 CPU 中断来完成。接口逻辑的任务是代表 UART 触发此类中断。两种机制(轮询或中断驱动)都有优点和缺点。
在另一个方向上,发送数据时,存在类似的问题。CPU 需要“足够快”地传递数据,以防止缓冲区下溢。这不是致命的,但会降低串行通信的性能和效率。CPU 也可以“过快”地将数据传递给 UART,导致 UART 中的发射机缓冲区溢出。这可以通过轮询(CPU 检查 UART 是否准备好发送)或中断(UART 通知 CPU 它需要更多数据)来控制。同样,接口逻辑必须提供实现这两种工作模式中的一种或两种的方法。
接口逻辑决定了程序员如何以及在何处找到他/她要编程的 UART,以及他/她可以以何种工作模式(轮询、中断驱动)发送和接收数据。例如,现代 PC 中的接口逻辑在某种程度上是可编程的。但是,这通常由 BIOS 完成(设置 I/O 地址和中断号)。在较旧的 PC 和许多其他计算机中,接口逻辑不可编程。从应用程序开发人员的角度来看,很少有必要对接口逻辑进行编程。通常,它被视为硬连线逻辑。
为了对特定的硬件进行编程,需要了解
- 如何访问 UART 和波特率生成器(接口逻辑如何工作)。这通常需要了解一些 I/O 或内存地址。
- UART 和波特率生成器的通信方式(接口逻辑是否提供轮询或中断,或者两者都提供?)。
- 如何对 UART 进行编程。为此,提供 UART 的数据手册非常有用。
- 如何对波特率生成器进行编程,这可能只是 UART 芯片的一部分。
或者,可以使用操作系统的串行编程 API,该 API 应该知道所有这些,并“做正确的事情”。
- 页面编程 8250 UART提供了在特定硬件组合中对特定 UART 进行编程的详细信息。
串行编程: 介绍和 OSI 网络模型 -- RS-232 接线和连接 -- 典型 RS232 硬件配置 -- 8250 UART -- DOS -- MAX232 驱动器/接收器系列 -- Windows 中的 TAPI 通信 -- Linux 和 Unix -- Java -- Hayes 兼容调制解调器和 AT 命令 -- 通用串行总线 (USB) -- 形成数据包 -- 错误校正方法 -- 双向通信 -- 数据包恢复方法 -- 串行数据网络 -- 实际应用开发 -- IP 通过串行连接