介绍
POSIX 串口编程指南将教会你在你的 UNIX 工作站或者 PC 上面如何成功、有效以及可移植性的对串口编程。每一章提供了使用 POSIX 终端控制函数的编程例程,可以基本不经修改地工作在 IRIX®, HP-UX, SunOS®, Solaris®, Digital UNIX®, Linux® 以及其他大多数 UNIX 操作系统。你会发现操作系统之间的最大差异是串口设备文件名和锁文件。
原文链接:Serial Programming Guide for POSIX Operating Systems
本指南分为以下章节和附录:
- 第一章 串口通信基础
- 第二章 串口配置
- 第三章 MODEM 通信
- 第四章 高级串口编程
- 附录A 引脚分布
- 附录B ASCII 码
第一章 串口通信基础
本章介绍了串口通信,RS-232 和 大多数计算机上使用的其他标准,以及如何通过 C 程序操作串口。
什么是串口通信
计算机一次传输信息(数据)一位或多个比特位。串行是指传输数据一次只传输一位。当进行串口通信时你发送或者接收的每个字(即字节或字符)一次发送一位。每一位都是 on 或者 off。术语用mark代表 on,用 space代表 off。
串口数据速率使用 bits-per-second ("bps") 或者 baudot rate ("baud")。这表示一秒内可以传输多少逻辑 1 和 0。当波特率超过 1000,你会经常看到用 kilo baud 表示的速率。对于超过 1000000 的速率用 megabaud,或者 Mbps 来表示。
当涉及到串口设备或者端口,它们被标识为“数据通讯设备”("DCE")或者“数据终端设备”("DTE")。两者之间的区别很简单 - 每个信号对,如发送和接收,是交叉的。
什么是 RS-232
RS-232 是由 EIA 定义的用于串口通信的标准电气接口。RS-232 实际上有三种不同的类型(A,B和C),每一种对于 on 和 off 电平定义了不同的电压范围。最常用的种类是 RS-232C,它定义mark位电压范围:-3V~-12V 和space位电压范围:+3V~+12V。RS-232C 规范上说,这些信号可以传输 25英尺(8m),通常你可以传输更远一些只要波特率足够低。
除了数据输入和输出数据线,还有其他提供时序、状态与握手的信号线。这里我们仅列举最为常见的 DB-9 接口分布图,引脚和功能描述如下所示:
- 1 - DCD - 数据载波检测
- 2 - RXD - 接收数据
- 3 - TXD - 发送数据
- 4 - DTR - 数据终端就绪
- 5 - GND - 地
- 6 - DSR - 数据装置就绪
- 7 - RTS - 请求发送
- 8 - CTS - 清除发送
- 9 - RI - 振铃指示
你还可能遇到 RS-422 以及 RS-485 串口标准。RS-422 使用更低电压与差分信号允许线缆长达 1000英尺(300m)。在实际应用中,使用 TTL 电平逐渐成为趋势,在 MCU 与串口转接芯片提供的串口中比较常见,此时mark 电平:+5V或+3.3V等,space位:0V(逻辑地)。
信号定义
RS-232 标准针对串口通信定义了18种不同的信号。其中,在 UNIX 环境下通常只有 6 种可用。
GND - 逻辑地
从技术上讲,逻辑接地不是信号,但没有它,其他信号就不能工作。从根本上说,逻辑地充当一个参考电压,从而知道哪些电压为正或负。
TXD - 发送数据
mark 电平为逻辑 1,space 电平为逻辑 0。注意 RS232 电平与 TTL 电平反相。
RXD - 接收数据
同样的,mark 电平为逻辑 1,space 电平为逻辑 0。注意 RS232 电平与 TTL 电平反相。
DCD - 数据载波检测
DCD 信号接收自串口线缆的另一端的计算机或设备。信号线低电平表示计算机或设备当前已连接或在线。DCD 不经常使用。
DTR - 数据终端就绪
DTR 信号用于通知对端计算机或设备己方已就绪(space 电平)或未就绪(mark 电平)。DTR 通常在打开串口时自动使能。
CTS - 清除发送
CTS 信号接收自串口线缆的另一端。信号线 space 电平表示可以己方可以发送数据。CTS 通常用于串口数据流控。
RTS - 请求发送
RTS 设置为 space 电平表示己方准备好就接收数据。一般与 CTS 一起用于串口流控,通常被设置为默认有效状态。
异步通信
解析串口数据需要确定一个字符的结束与下一个字符的开始。本章专门讲述异步串口数据。
在异步模式下串口数据线保持在 mark 状态(逻辑 '1')直到有字符发送,也即串口的空闲态是 mark 态。每个字节起始位在前,字节的每一位紧随其后,一位可选校验位以及一位或者两位停止位。起始位始终是 space 电平(逻辑'0'),通知对方有新串口数据可用。数据可以同时发送和接收,因此称为“异步”。
可选校验位是数据位的简单累加和,指示数据是否包含奇数或者偶数个 1。偶校验时,如果一个字符中有偶数个 1 那么校验位是 0。奇校验时,如果一个字符中有奇数个 1 那么校验位是 0。除此之外,你还可能听过术语 space 校验,mark 校验以及无校验。Space 校验指示校验位永远是 0,而 mark 校验是指校验位一直为 1。无校验意味着没有校验位存在或被传输。
剩下的位称作停止位。在字符之间可能会有 1,1.5 或者 2 位停止位并且这些位总为 1。停止位过去用于腾出时间为硬件处理之前的数据,但现在只用于接收字符与硬件设备的同步。异步数据格式通常表达成“8N1”,“7E1”等。
什么是全双工和半双工
全双工是指设备可以同时发送和接收数据 - 有两个独立数据通道(一路输入,一路输出)。
半双工是指设备不能同时发送和接收数据。这通常意味着只有一路可以通讯。这并不代表有任何的 RS-232 信号未被使用,相反,这通常意味着使用的一些非 RS-232 标准的通讯链路不支持全双工操作。
流控
在两个串口设备间传输数据时经常有必要进行数据流控。这可能是受到中间串口通信线路、其中一个设备或者其他存储介质的限制。异步数据流控通常使用的有两种方法。
第一种方法通常称为“软件”流控,使用特殊字符开始(XON or DC1)或者停止(XOFF or DC3)数据流。这些字符定义参见 ASCII 码表。这些码值在传输文本信息时很有用,但不能在未经特殊编程时用于传输其他类型的信息。
第二种方法称作“硬件”流控,使用 CTS 和 RTS 信号线取代特殊字符。当接收方准备好接收数据时会将 RTS 置为 space 电压以请求对方发送数据,当未准备好时置为 mark 电压,因此发送方会通过检测 CTS 电平状态判断是否可以发送数据。由于硬件流控使用独立的信号集合,因此比软件流控速度要快。
Break信号
通常情况下收发数据信号线保持在 mark 电平状态直到传输一个新字节。如果信号拉低至 space 电压一段时间,通常是 1/4 到 1/2 秒,那么就说一个 break 条件满足。一个 break 信号有时用于复位通讯或者改变通讯硬件的操作模式,如 MODEM。
同步通信
不同于异步数据,同步数据以恒定比特流显示。为了读取数据,通讯方必须提供或接收一通用位作为时钟使发送和接收者同步。
尽管有时钟同步,通讯方也必须以某种方式标记数据开始。实现的最常用方法是使用像“串行数据链路控制”(“SDLC”)或者“高速数据链路控制”(“HDLC”)的数据包协议。
每种协议定义了一定的位序列来表示数据包的开始和结束,也定义了没有数据时的位序列。这些位序列使得通讯方明确数据包的开始。由于同步协议不使用每字节同步位它们比异步通信有至少25%的性能提升并且在多余两个串口的情形下更适合于远程网络和配置。
尽管同步通信有速度优势,由于需要额外的软硬件大多数 RS-232 硬件不支持。
编程指南的其他章节内容我先前翻译过,但是由于内容和部分知识点较为陈旧,因此我用其他整录的博客系列 -《Linux 串口编程》中进行详细讲解,感兴趣的可以移步至:
- 《Linux 串口编程<一> 一些背景》
- 《Linux 串口编程<二> 深入了解 termios》
- 《Linux 串口编程<三> 使用termios与API 进行串口程序开发》
- 《Linux 串口编程<四> 串口设备程序开发》