RS232、RS485和TTL电平与串行通信
RS232、RS485和TTL
作为一个底层软件开发工程师,经常会碰到RS232、RS485和TTL这一类的问题。
之前总是碰到问题之后Google一下,把当下的问题解决了之后就不管了,过个一两天就忘得一干二净,结果后续每次都会碰到类似的问题,都是从零开始地去解决,这种方式看起来当时快速解决了问题,结果在后续的开发中浪费了更多的时间。
为了解决这个问题,博主决定一次性把这些东西给弄清楚
串行通信
串行通信是指 使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。
其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的短距离通信。
串行通信在传输方式上分为同步通信和异步通信,在传输方向上分为单工通信,半双工通信,全双工通信。
同步通信
顾名思义,同步通信需要通信双方进行数据同步,一般表现为通信双方在时钟线上的统一,双方在在数据的收发上是同时的,根据时钟线的跳变来操作数据线实现发送(读取),常用的同步协议有SPI I2C。
异步通信
异步通信不需要建立数据同步即可传输数据,发送方按照一定的协议格式来发送数据,接收方接收到数据再根据协议进行解析,双方的收发不需要同时进行,也不需要进行传输时的校验,RS232,485和UART就属于这一类。
同步通信和异步通信的比较
在这里,我们不妨可以先思考一下,同步通信和异步通信最根本的区别是什么?
同步通信,通信双方遵循相同的时钟,每一个帧数据的收发都是需要经过双方共同确认,然后再进行下一帧传输。
而异步通信则不然,在发送发看来,需要发送数据的时候,只负责把数据发出去就行了,接受方到底收没收到或者怎么解析不需要发送方操心。
从上述的原理上的区别出发,我们以发送0x55(01010101b)为例,可以发现两者通信的区别:
在同步发送中,数据线上只需要根据时钟发送数据01010101,接收方同时也可以根据时钟来解析收到的数据。
但是在异步发送中,因为没有时钟同步,如果发送方仅仅将数据01010101发送出来,接收方无法解析接收到的数据。原因有两个:
-
接收方不知道数据是以一个什么样的间隔时间发送过来的,可能发送方的时钟频率和配置决定了发送为1bit/us,但是接收方的时钟配置不一致,就出现解析错误。
-
接受方无法判断数据的开始和结束,如果数据线的默认电平为高,发送数据的第一位也为高,将难以判断数据是从哪里开始。
所以,针对这两个问题,异步通信提出了两个相应的解决方案:
- 通信双方遵循相同的传输速率,即波特率
- 在通信协议中加入开始位,结束位,校验位以实现数据的接收时解析。
同步通信和异步通信的优劣
-
可以看出,同步通信中的数据传输效率(注意是效率,非速率)要高于异步传输,同步传输效率一般能达到100%,而异步传输中传输的数据并非全是有效数据,像串口协议中,常用配置中(1停止位,无校验)传输一个字节需要传送10bit。
-
在更复杂的应用中,同步传输可以做到点对多点的传输,多点可以共用一个时钟线,可以轻松实现一点写,多点读的操作。而在异步通信中,无法确定接收方接收数据的时间,所以不适用于点对多点的传输。
-
在相同的时钟频率下,传输效率高的同步通信自然能达到更高的数据吞吐量。
-
异步传输在传输效率上比同步传输低,但是同时也省去了同步所需要的时间,尤其是在远距离传输时,时钟同步所带来的开销也是不容忽视的,所以在长距离的传输中,一般使用异步通信,如RS485就支持KM级别的距离传输,而SPI I2C一般都用于板级通信。
-
异步传输不需要时钟线,更容易实现且节省资源。
单工通信
单工即单向通信,在整个数据传输的过程中只允许定向地传输数据
半双工通信
双工即双向通信,半双工指的是在同一时刻,只允许一个方向的发送接收,就像两个人打电话,A可以对B说话,B可以对A说话,但是A/B不能同时说话,那样会造成混乱。
全双工通信
全双工通信就是允许数据在两个方向上同时传输。数据的收和发之间不会相互影响。
RS232 RS485 TTL电平
RS232 RS485 TTL同属于异步串行通信,这三种通信方式本质上是电平逻辑的区别。
RS232
RS232多用于电脑的串口,目前使用最广泛的就DB9接口,即九线接口,目前一般的电脑主机后面都会有这样的接口.
RS232电平采用负逻辑,
-15V ~ -3V 代表逻辑1
+3V ~ +15V 代表逻辑0
-3V ~ +3V 无意义
在早期还有DB25线的接口,后来IBM将标准改成9线接口。
这种信号传输方式决定了一根数据线即可实现数据传输,所以两根信号线(TX RX)即可实现全双工地数据传输,上图中的其他信号脚类似于RTS/CTS等都是用于差错控制,在较简单的应用中只需要GND RX TX即可。
RS232电平传输方式有一些明显的缺点:
- 接口的信号电平值相对太高,容易损坏接口电路的芯片。
- 传输速率比较低,在异步传输时,波特率只有20Kbps。
- 接口使用一根信号线和一根信号返回线回路构成共地的传输模式,很容易产生共模干扰,所以抗噪声比较弱。
- 由于抗干扰能力弱,易产生共模干扰,所以传输距离并不远。
针对RS232在这些方面的不足,于是不断出现了一些新的标准,其中RS485是使用比较广泛的标准。
RS485
RS485多用于长距离传输的应用场景,大多数是在工业场景中,RS485电平逻辑采用差分电平,即传输数据至少需要两根信号线,根据两根信号线电压的差值来确定电平逻辑,发送端电平:
+2V ~ +6V 代表逻辑1
-2V ~ -6V 代表逻辑0
其他 无意义
接收端电平:
> +200mv 代表逻辑1
< -200mv 代表逻辑0
其他 无意义
由于在传输数据时需要两根信号线同时工作,所以RS485只能做到半双工通信,在RS232上依然有以下优化:
- 差分信号抗干扰能力强
- 传输距离大大加长,可以达到KM级别的传输
- 相对应RS232而言可以支持多点传输甚至联网构成分布式系统。
- 传输速率可达到10M/bps。
TTL电平
目前我们熟知的单片机基本上都是使用的TTL电平的信号系统,这是计算机处理器控制的设备内部各部分之间通信的通信标准。
TTL集成电路的全名是晶体管-晶体管逻辑集成电路(Transistor-Transistor Logic)。在传统的单片机系统中,VCC(供电电压)为5V,电平标准为:
输出:
小于0.8V 代表逻辑0
大于2.4V 代表逻辑1
输入:
小于1.2V 代表逻辑0
大于2.0V 代表逻辑1
其他 无意义
因为2.4V和5V之间还有很大的空闲,白白增加了系统的功耗,同时影响了速度,所以来后就把一部分砍掉了,也就是后来的LVTTL,LVTTL又分为3.3V、2.5V甚至更低电压的LVTTL(Low Voltage TTL).在3.3V LVTTL,Vcc = 3.3V中,电平标准为:
输出:
大于2.4V 代表逻辑1
小于0.4V 代表逻辑0
输入:
小于0.8V 代表逻辑0
大于2V 代表逻辑1
其他 无意义
TTL电平输入脚悬空时是内部认为是高电平。要下拉的话应用1k以下电阻下拉。
TTL电平无法进行长距离传输,抗干扰能力弱,信号衰减较大。
TTL电平为逻辑电平而设计,基本用于板级通信,单片机基本上都使用TTL信号系统。
无意义的电平
在上面的电平描述中,都提到了无意义的电平,事实上在数据的接收中,如果接收到一个无意义的电平,这时候的逻辑输出是不确定的,有可能是正确的,有可能是错误的。
例如,RS232的系统中,需要传输数据0x55(01010101b),但是在传输过程中由于干扰,最低位的数据1电平在接收端为0V,即无意义电平,其他位正常,这时候在接收端的解析中可能出现接收数据为0x54和0x55的结果,即无意义电平的解析是不确定的,可能是正确结果,也可能不是。
串行通信流控
串行通信中的流控制
这里讲到的流,指的是数据流,数据在两个串口之间传输时,常常出现一些意料之外的情况,比如通信双方速率不一致,又或者是接收端缓冲区溢出导致数据丢失等等。
流控制专门为了解决这些问题而生,例如,当接收端的数据处理不过来时,就可以发出“不再接收”的信号,发送端收到信号马上停止发送,等接收端可以继续接收之后,再发送“继续接收”的信号提醒发送端继续发送。
流控制一般分为硬件流控制和软件流控制,顾名思义,硬件流控制需要硬件上的支持,常用的有rts/cts,dts/cts信号线,流控制的信号在这些信号线上传输,而软件流控制则是由软件来实现,在传输过程中定义特殊字段来作为流控制信号。
硬件流控制
硬件流控制必须将相应的电缆线连上,用rts/cts(请求发送/清除发送)流控制时,应将通讯两端的rts、cts线对应相连,数据终端设备(如计算机)使用rts来起始调制解调器或其它数据通讯设备的数据流,而数据通讯设备(如调制解调器)则用cts来起动和暂停来自计算机的数据流。
这种硬件握手方式的过程为:
在编程时根据接收端缓冲区大小设置一个高位标志(可为缓冲区大小的75%)和一个低位标志(可为缓冲区大小的25%),当缓冲区内数据量达到高位时,我们在接收端将cts线置低电平(送逻辑0)。
当发送端的程序检测到cts为低后,就停止发送数据,直到接收端缓冲区的数据量低于低位而将cts置高电平。
rts则用来标明接收设备有没有准备好接收数据。
软件流控制
由于电缆线的限制,我们在普通的控制通讯中一般不用硬件流控制,而用软件流控制。一般通过xon/xoff来实现软件流控制。
常用方法是:当接收端的输入缓冲区内数据量超过设定的高位时,就向数据发送端发出xoff字符(十进制的19或control-s,设备编程说明书应该有详细阐述),发送端收到xoff字符后就立即停止发送数据;当接收端的输入缓冲区内数据量低于设定的低位时,就向数据发送端发出xon字符(十进制的17或control-q),发送端收到xon字符后就立即开始发送数据。一般可以从设备配套源程序中找到发送的是什么字符。
但是这种流控制仅仅适用于字符流传输的情况,如果是传输二进制数据,很可能数据内容中就带有xoff字符导致出现差错,所以软件流控制还是有比较大的缺陷。
不同电平之间的相互转换
在嵌入式的软件开发过程中,经常要用到不同设备之间的串口通信,既然这些串口分属于不同的电平信号系统,自然是不能直接进行通信的。
比如:将RS232的TX连接到TTL电平的RX时,发送端发送逻辑0信号为+10V,但是+10V的信号很可能直接将TTL端的芯片损坏,因为TTL端只支持0~5V的电平,所以在双方进行通信的时候,需要对电平进行转换才能进行通信。
对于电平的转换,网上已经有非常成熟的方案可以直接使用:
好了,关于串行通信的问题讨论就到此为止了,如果朋友们对于这个有什么疑问或者发现有文章中有什么错误,欢迎留言
个人邮箱:linux_downey@sina.com
原创博客,转载请注明出处!
祝各位早日实现项目丛中过,bug不沾身.
(完)
TTL电平部分参考:https://blog.csdn.net/lijiuyangzilsc/article/details/48599745