zoukankan      html  css  js  c++  java
  • RS232、RS485和TTL电平与串行通信

    RS232、RS485和TTL

    作为一个底层软件开发工程师,经常会碰到RS232、RS485和TTL这一类的问题。

    之前总是碰到问题之后Google一下,把当下的问题解决了之后就不管了,过个一两天就忘得一干二净,结果后续每次都会碰到类似的问题,都是从零开始地去解决,这种方式看起来当时快速解决了问题,结果在后续的开发中浪费了更多的时间。

    为了解决这个问题,博主决定一次性把这些东西给弄清楚

    串行通信

    串行通信是指 使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。

    其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的短距离通信。

    串行通信在传输方式上分为同步通信和异步通信,在传输方向上分为单工通信,半双工通信,全双工通信。

    同步通信

    顾名思义,同步通信需要通信双方进行数据同步,一般表现为通信双方在时钟线上的统一,双方在在数据的收发上是同时的,根据时钟线的跳变来操作数据线实现发送(读取),常用的同步协议有SPI I2C。

    异步通信

    异步通信不需要建立数据同步即可传输数据,发送方按照一定的协议格式来发送数据,接收方接收到数据再根据协议进行解析,双方的收发不需要同时进行,也不需要进行传输时的校验,RS232,485和UART就属于这一类。

    同步通信和异步通信的比较

    在这里,我们不妨可以先思考一下,同步通信和异步通信最根本的区别是什么?

    同步通信,通信双方遵循相同的时钟,每一个帧数据的收发都是需要经过双方共同确认,然后再进行下一帧传输。

    而异步通信则不然,在发送发看来,需要发送数据的时候,只负责把数据发出去就行了,接受方到底收没收到或者怎么解析不需要发送方操心。

    从上述的原理上的区别出发,我们以发送0x55(01010101b)为例,可以发现两者通信的区别:

    在同步发送中,数据线上只需要根据时钟发送数据01010101,接收方同时也可以根据时钟来解析收到的数据。

    但是在异步发送中,因为没有时钟同步,如果发送方仅仅将数据01010101发送出来,接收方无法解析接收到的数据。原因有两个:

    1. 接收方不知道数据是以一个什么样的间隔时间发送过来的,可能发送方的时钟频率和配置决定了发送为1bit/us,但是接收方的时钟配置不一致,就出现解析错误。

    2. 接受方无法判断数据的开始和结束,如果数据线的默认电平为高,发送数据的第一位也为高,将难以判断数据是从哪里开始。

    所以,针对这两个问题,异步通信提出了两个相应的解决方案:

    1. 通信双方遵循相同的传输速率,即波特率
    2. 在通信协议中加入开始位,结束位,校验位以实现数据的接收时解析。

    同步通信和异步通信的优劣

    • 可以看出,同步通信中的数据传输效率(注意是效率,非速率)要高于异步传输,同步传输效率一般能达到100%,而异步传输中传输的数据并非全是有效数据,像串口协议中,常用配置中(1停止位,无校验)传输一个字节需要传送10bit。

    • 在更复杂的应用中,同步传输可以做到点对多点的传输,多点可以共用一个时钟线,可以轻松实现一点写,多点读的操作。而在异步通信中,无法确定接收方接收数据的时间,所以不适用于点对多点的传输。

    • 在相同的时钟频率下,传输效率高的同步通信自然能达到更高的数据吞吐量。

    • 异步传输在传输效率上比同步传输低,但是同时也省去了同步所需要的时间,尤其是在远距离传输时,时钟同步所带来的开销也是不容忽视的,所以在长距离的传输中,一般使用异步通信,如RS485就支持KM级别的距离传输,而SPI I2C一般都用于板级通信。

    • 异步传输不需要时钟线,更容易实现且节省资源。

    单工通信

    单工即单向通信,在整个数据传输的过程中只允许定向地传输数据

    半双工通信

    双工即双向通信,半双工指的是在同一时刻,只允许一个方向的发送接收,就像两个人打电话,A可以对B说话,B可以对A说话,但是A/B不能同时说话,那样会造成混乱。

    全双工通信

    全双工通信就是允许数据在两个方向上同时传输。数据的收和发之间不会相互影响。

    RS232 RS485 TTL电平

    RS232 RS485 TTL同属于异步串行通信,这三种通信方式本质上是电平逻辑的区别。

    RS232

    RS232多用于电脑的串口,目前使用最广泛的就DB9接口,即九线接口,目前一般的电脑主机后面都会有这样的接口.

    DB9
    RS232电平采用负逻辑,

    -15V ~ -3V  代表逻辑1
    +3V  ~ +15V 代表逻辑0
    -3V  ~ +3V  无意义
    

    在早期还有DB25线的接口,后来IBM将标准改成9线接口。

    这种信号传输方式决定了一根数据线即可实现数据传输,所以两根信号线(TX RX)即可实现全双工地数据传输,上图中的其他信号脚类似于RTS/CTS等都是用于差错控制,在较简单的应用中只需要GND RX TX即可。

    RS232电平传输方式有一些明显的缺点:

    1. 接口的信号电平值相对太高,容易损坏接口电路的芯片。
    2. 传输速率比较低,在异步传输时,波特率只有20Kbps。
    3. 接口使用一根信号线和一根信号返回线回路构成共地的传输模式,很容易产生共模干扰,所以抗噪声比较弱。
    4. 由于抗干扰能力弱,易产生共模干扰,所以传输距离并不远。
      针对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

  • 相关阅读:
    Python之路:堡垒机实例
    Django入门
    阿里云centos安装svn和submin
    发邮件功能
    [Coci2015]Divljak
    [2018多省省队联测]劈配
    [AHOI2009]最小割
    [HAOI2017]新型城市化
    [SDOI2014]LIS
    Loj #2256. 「SNOI2017」英雄联盟
  • 原文地址:https://www.cnblogs.com/downey-blog/p/10483504.html
Copyright © 2011-2022 走看看