- 想搞清楚linux下的终端(Terminal)、设备IO,以及Windows下的设备IO(可提醒IO、IO完成端口等),似乎这个古老的RS232串口还真是一个不错的切入点。所以,从基础开始,看看串口。
注:聆听Oswald Buddenhagen教诲,Windows首字符一定要大写,否则M$可能会不高兴的^_^
DTE与DCE
DTE | Data Terminal Equipment | 数据终端设备 |
DCE | Data Circuit-terminating Equipment | 数据通信设备 |
一直以来每理清这两个是什么东西,比如说,我用电脑通过232串口直接控制一个分子泵,那么谁是DTE、谁是DCE?
而理不清这个,就浑浑噩噩,始终弄不明白那些串口引脚如何工作的。原来:二者都是DTE
在远古时代,比如一个大型主机和一个终端设备进行通讯,二者之间需要调制解调器进行信号调制:
DTE <==> DCE <======...=====>DCE <==> DTE
而现在呢,我们使用的一般都是:
DTE <=====> DTE
不用于远距离传输,没有DCE什么事了。彼此都认为自己连接的都是DCE。
9针串口
- RS-232C规标准接口有25条线,4条数据线、11条控制线、3条定时线、7条备用和未定义线,常用的只有9根
所以: 只关注目前还算很常见的 DE-9 pin 接口。假定是PC和一个modem相连。
名字 | 引脚(从PC角度) | 信号起源 | 作用 |
DTD | 1 | DCE | 已经连接成功 |
DTR | 4 | DTE | 通知对方自己已经就绪 |
DSR | 6 | DCE | |
RI | 9 | DCE | 振铃 |
RTS | 7 | DTE | PC请求发送数据 |
CTS | 8 | DCE | |
TxD | 3 | DTE | 数据收发 |
RxD | 2 | DCE | |
GND | 5 | common | 公共地 |
连线
只考虑两个DTE连接的情况
3线
设备A | 设备B | |
TxD | ---> | RxD |
RxD | <--- | TxD |
Gnd | ---- | Gnd |
TxD与RxD交错链接,Gnd直连。
当直接这样连线时,可以更近一步,将自己的RTS与CTS、DSR与DTR分别连起来。
这样一来:
设备A | 设备B | |
TxD | ---> | RxD |
RxD | <--- | TxD |
Gnd | ---- | Gnd |
RTS | RTS | |
DTR | DTR |
效果就是,如果一方设置了硬件握手,发出握手请求的同时,就立即得到回应(尽管我们自己知道这是假的)。
5线
设备A | 设备B | |
TxD | ---> | RxD |
RxD | <--- | TxD |
Gnd | ---- | Gnd |
RTS | ---> | CTS |
CTS | <--- | RTS |
加入了 RTS/CTS 握手。
7线
如果真的要多用一些线,可以使用7线链接。(接法不统一,这只是其中一种。当然,前面3线都不会有变化任何变化)
每个DTE可以发出3个信号TxD、RTS、DTR,加Gnd互联,共7线。
设备A | 设备B | |
TxD | ---> | RxD |
RxD | <--- | TxD |
Gnd | ---- | Gnd |
RTS | ---> | DCD |
DCD | <--- | RTS |
DTR | ---> | DSR |
DSR | <--- | DSR |
这样一来 DTR/DSR 硬件握手就可以正常工作了。
- 当A方准备好,发出DTR信号,该信号直接联至B的RI和DSR。即只要A准备好,B立即产生呼叫有效,并同时准备好。
- A的RTS和CTS相连,并与B的DCD互连。即:一旦甲方请求发送(RTS),便立即得到允许(CTS),同时,使B的DCD有效,即检测到载波信号
流向控制
硬件流控
- RTS(Request To Send)/CTS(Clear To Send) 流控
- DTR(Data Terminal Ready)/DSR(Data Set Ready) 流控
软件流控
- XON/XOFF
RTS/CTS
原本含义(主要是半双工MODEM系统中发送方式和接收方式之间的切换):
- RTS 用来表示DTE想DCE请求发送数据,即当终端要发送数据时,使该信号有效(ON),向MODEM请求发送。它用来控制MODEM是否要进入发送状态。
-
CTS 用来表示DCE准备好接收DTE发来的数据,是对请求发送信号RTS的响应信号。当MODEM已准备好接收终端传来的数据,并向前发送时,使该信号有效,通知终端开始沿发送数据线TxD发送数据。
后来的变化(全双工):
- CTS 不再是 RTS的响应,它用来表示DCE是否允许发送数据。
windows
DCB 相关成员:
fRtsControl | RTS_CONTROL_DISABLE 使得RTS保持off |
RTS_CONTROL_ENABLE 使得RTS保持on | |
RTS_CONTROL_HANDSHAKE 启用RTS握手 | |
RTS_CONTROL_TOGGLE 根据有无数据可发送切换状态 | |
fOutxCtsFlow | 是否根据CTS的状态才确定数据收发 |
DTR/DSR
DTR/DSR 一般情况下始终为ON,通常用来通知对方设备是否连接正常并已经加电(powered-up)。
- DSR 有效时(ON)状态,表明MODEM处于可以使用的状态
- DTR 有效时(ON)状态,表明数据终端处于可以状态
但是设备制造商实现了各个非标准的变体,比如用来进行流控^_^
windows
DCB 相关成员:
fDtrControl | DTR_CONTROL_DISABLE 保持off |
DTR_CONTROL_ENABLE 保持on | |
DTR_CONTROL_HANDSHAKE 启用硬件握手 | |
fOutxDsrFlow | 是否根据DSR的状态确定数据收发 |
fDsrSensitivity | 是否只接受DSR为on时的数据 |
XON/XOFF
缩写词XOFF与 XON源于:transmit off 和 transmit on。x代表transmit/transmitter/....,前面遇到的 RxD,TxD也是这种情况。
ASCII码值,十进制 | 名字 | 对应键盘按键 | |
19 | DC3(Device Control 1 ) | CTRL+S | ^S |
17 | DC1(Device Control 1 ) | CTRL+Q | ^Q |
软件流控使用这两个字符,是一个事实标准。
注意:当使用这种流控方式时,两个字符在带内(in band)传递,所以我们将无法再直接传输这两个字符,而只能自己根据需要进行转义。
为了健壮性,某些串口打印机每隔1~30秒发送一次 XON,以表明他们在线且准备好接受数据。
Windows
DCB结构中相关的成员:
fOutX | 数据发送时是否使用软件流控(收到XOFF停止发送数据,收到XON重新开始) |
fInX | 数据接收时是否使用软件流控(当前缓冲区快满时发送XOFF,有空间时发送XON) |
fTXContinueOnXoff | 因接受缓冲区快满而发送XOFF后,继续发送发送缓冲区数据还是等待发送XON以后继续 |
XonChar | 设置我们前面提到的2个流控字符 |
XoffChar |