我刚入行那会儿,接手第一个带RS485接口的项目,心里想的是:不就是两根线嘛,A接A、B接B,波特率设对了就能通,能有多大事。
后来我被现实抽了无数个嘴巴子。同样的接线方式,这个项目跑得稳稳当当,换到另一个现场就连不上。同一个设备,今天调通了明天又不行了。最邪门的一次,上午还能收数据,下午就全是乱码,查了一圈发现是旁边那台大功率变频器开机了。
RS485这东西,看着比RS232复杂不到哪去,就是一个差分信号、半双工、能挂多个设备。但真到了现场你就明白了,说明书上写的"理论最远1200米""理论挂载32个节点",跟实际能用完全是两码事。
今天就按照我自己这些年踩坑的经验,一条一条说清楚,RS485到底是个什么玩意儿,以及它到底有多能折腾人。
先整明白RS485是干什么的
要理解RS485,得先明白它跟RS232的区别。
RS232是点对点的,一根线只能连一台设备,通信距离也就十几米。RS485是差分信号传输,用两根线,A和B,靠两根线之间的电压差来表示0和1。差分信号抗干扰能力强,所以距离能拉到几百上千米,而且可以挂多个设备在一条总线上。
工业现场为什么普遍用RS485?就仨原因:距离远、抗干扰、能挂多台设备。
但它有个要命的限制,半双工。就是你发数据的时候不能收,收的时候不能发,一根线上同一时刻只能有一个设备在说话。这就意味着你得轮着来,一台设备说完了下一台才能接着说,大家排队,不能抢。
我刚接触485的时候,总是下意识拿它当232用,觉得不就是两根线收发嘛。后来被"半双工"这个特性坑了好几次才长记性。你发完数据之后不能马上切换接收,得等一小段时间让总线稳定下来,不然切换太快了,总线上的电平还没稳定,收到的数据里前面几个字节全是错的。
第一个坑:线接对了,但是没接好
RS485只有两根数据线,A和B,有些设备还带一根地线GND。很多人的接线方式是直接把A对A、B对B一拧,胶布一缠,完了。
我最早也这么干,后来出了个事。现场有两百多米远的一台仪表,数据时通时不通,有时候一整天都正常,有时候一上午断七八次。我去了现场,把线重新接了一遍,好了一天,第二天又不行了。
后来老师傅过来看了一眼,说你的屏蔽层接了吗?RS485的屏蔽线,就那根网线外头包着的金属编织层,你得把它接到设备的接地端子上,不然就成了天线,到处接收干扰。我那根线用了普通的双绞线,根本没屏蔽层,能不丢数据吗。
换了带屏蔽的双绞线,屏蔽层单端接地,问题解决了。
从那儿以后我的接线规矩是这样的:必须用双绞线,A和B一对绞在一起,抗共模干扰。屏蔽层只在设备端接地,PLC那边浮空或者也接地但两头接地不行,两头接地会形成地环路,干扰更大。线径不能太细,超过三四百米我用0.75平方毫米以上的线。
还有一个更基础但很多人不知道的事。RS485的两个终端要各接一个120欧姆的终端电阻,A和B之间并联上去。为什么?因为485总线上的信号走到尽头如果没电阻匹配,会反射回来,跟后面的信号混在一起,数据就错了。
我第一次听到这个说法的时候,觉得"终端电阻"这名字听着就高级,肯定要买专用的东西。后来发现其实就是个普通电阻,1/4瓦的就行,120欧姆,往接线端子上一塞一拧,完事。便宜的几毛钱一个。
当然这个电阻也不是什么时候都接。总线上的设备只有两个,一头一尾各接一个。如果中间某个设备接了这个电阻,反而会把总线电平拉偏,设备多了驱动能力不够,信号就畸变了。我的做法是:我自己的设备上不焊这个电阻,留个跳线或者拨码开关,现场根据实际情况决定要不要接。
第二个坑:手拉手不是你想的那样
RS485的接线方式是手拉手,就是一台设备出线接到第二台设备,第二台再接到第三台,串起来一条总线。不是从一台设备分叉出去接好几台,那是星形接法,RS485不能这么干。
我以前犯过一个低级错误,在配电柜里把四台仪表的485线全拧到一个接线排上,想着这不就是并联嘛,跟电路一样。结果死活通信不上,偶尔能收上来一两个字节全是乱码。
后来查了资料才知道,星形接法导致信号在分叉点反射,四个分支的信号互相干扰,设备多了驱动器的负载也不够。标准做法就是手拉手,一条主线从头串到尾,设备就挂在主线上。
如果现场布局限制,非得走星形怎么办?也有办法。我后来用了个叫RS485集线器的东西,也叫HUB,它能把星形的各路信号隔离整形之后再合并到一起。好一点的带光电隔离,每个端口独立驱动,能解决大部分布线问题。但这东西是额外成本,能不用就不用,布线阶段就按手拉手来。
第三个坑:数据能收发,但总有乱码
这是最折磨人的一种情况。接线没问题,终端电阻也加了,波特率也对得上,但时不时收上来的数据里总有一两个字节是错的。
我碰见这情况头一回的时候,翻了三天代码,把CRC校验改了三遍,查缓冲区逻辑查了无数遍,最后发现是波特率偏差的问题。
事情是这样的。有些国产设备,用的晶振精度不高,标称9600的波特率,实际跑出来的可能是9580或者9620。偏差在正负百分之二三以内,单独一台设备跟电脑通信看不出来,偶尔错一个字节你以为是干扰。但你要是总线上挂了很多台设备,每台的波特率偏差方向还不一样,有的偏快有的偏慢,数据就乱得一塌糊涂。
后来我养成了一个习惯,所有项目里能设波特率的地方,一律用低一点的,9600比19200稳定,19200比38400稳定,能跑9600就不往上跑。速度慢一点,容错空间大一点。
还有一个被很多人忽略的点是收发切换的时间。RS485是半双工,你从发送状态切到接收状态,得给硬件留点时间。我以前写过这样的代码:发完数据立刻把485芯片的收发控制脚拉低切换到接收模式,然后马上开始读串口。结果总是读不到数据或者读到半包。
后来在发完数据之后加了个延时,根据波特率算了一下,9600波特率下大概延时个两三毫秒就够了。加了延时之后,一切正常。
这个逻辑我后来封装成固定的写法:发完数据,串口缓冲区的数据确保全部发送完毕,然后延时两毫秒,再切换收发控制脚,再开始接收。顺序不能反,先确保发完再切方向。
第四个坑:没共地,通信就不稳
RS485是差分信号,理论上不需要共地,两根线A和B就能传数据。
但实际现场,我建议你还是把地线接上。为什么?因为RS485虽然不靠地线传信号,但它有个共模电压的容限范围,大概是负七伏到正十二伏。如果两端的设备地电位不一样,比如设备A的地是0伏,设备B的地因为距离远或者接地不良,飘到了5伏,那么A发过来的信号到了B这边,共模电压就超标了,信号就识别不了。
这也就是为什么有时候两台设备离得近通信正常,同样两台设备拉远到几百米就通不了。远了之后地电位差变大,共模电压超标了。
解决的办法就是把各台设备的GND用一根线连起来,让它们的地电位保持一致。但不是所有设备都有GND端子,没有的话我就把屏蔽层接上,也能起点作用。
还有一种情况是两边的设备电源不共地,用的是不同的开关电源。这时候更要接GND线,不然地电位差可能大到几十伏,轻则通信不稳,重则烧毁接口芯片。我干过这事儿,把一台仪表的485口烧了,一股糊味儿,就是因为没共地,两边地电位差太大了。
第五个坑:带电插拔,最容易出大事
这算是一个教训。
以前调试的时候图方便,设备不断电直接拔485线,换到另一台设备上接着调。有一回拔的时候,线头碰到了旁边220伏的端子,一声响,火花一冒,我手一哆嗦,那块USB转485转换器直接烧了。
更惨的是有一次,我把带电的485线插到一台仪表上,仪表直接冒烟了。那台仪表两千多块,厂家不给保修,因为是"用户操作不当造成的损坏"。
后来我买了带隔离的转换器,贵是贵了点,但至少电脑这边的串口口再也不会被烧了。设备那边的接口该烧还是烧,只是把损坏隔离在了转换器这一侧,不会殃及电脑。但最好还是养成习惯,断电之后再接线,别图那几秒钟的快。
说说实际项目里的经验数字
干了这么多年,有些数字是我自己用出来的,不是说明书上的理论值。
距离方面,9600波特率下,我用过最长的线是八百多米,屏蔽双绞线,中间加了一个中继器,跑得还行,偶尔丢包但不频繁。再远我就不敢保证稳定了,要么换光纤转换器,要么走以太网。
节点数量方面,标准的RS485驱动器理论上能带32个节点,但我的实际经验是,超过15个最好加个中继器或者换成高阻输入的驱动器。节点越多,总线负载越大,信号幅度越低,抗干扰能力越差。我遇到过一个项目,总线上挂了二十台设备,波特率降到2400才勉强跑稳定。
速率方面,我现在有个习惯,能用多低就用多低。9600用不了降4800,4800还不行降2400。现场稳定压倒一切,速度快那点优势在稳定性面前不值一提。有次一个甲方非要让我跑115200,我说跑可以,但不保证长期稳定。结果三个月后丢包严重,又让我改回9600了。
布线方面,485线绝对不能跟动力线走同一个线槽。电缆沟里,动力线和信号线之间必须隔开,至少十厘米以上。穿管的话分两根管走,别往一根PVC管里塞。变频器、大电机这类设备,跟它的线保持一米以上的距离,变频器的高频谐波能通过空间耦合到你485线上,那干扰根本压不住。
再说点有用的经验
排查485故障的时候,我有个常用的笨办法。拿个USB转485的转换器挂到总线上,打开串口调试助手,监听总线上所有设备的数据。哪个设备没回数据、哪个设备回了错误数据、哪个设备一直在发数据霸占着总线,一看就知道谁在捣乱。
有时候总线上某台设备坏了,它会一直往总线上发数据,别的设备想说话都说不了,因为485是半双工的,有人占着线其他人就发不了。用调试助手一看,全是那台设备的数据流,直接拔掉,总线马上恢复正常。换个新的上去就行。
还有个排查工具是万用表。测A和B之间的电压,设备在空闲状态下,A和B之间的电压应该在负一点几伏到负二点几伏之间(A相对B为负,代表空闲电平)。如果你测出来A和B之间是正电压或者0伏,说明总线上有设备一直在发数据或者某台设备的收发控制脚卡在发送状态了。
再不行就拿示波器抓波形。虽然大部分现场调试没这条件,但要是条件允许,一看波形什么都清楚了。信号边沿陡不陡、有没有过冲、幅值够不够、空闲电平对不对,一目了然。
最后几句实在话
RS485就是一根破线,两根芯加一层屏蔽皮。但这根线能把你折腾得死去活来。我见过工厂里用了十年的老线,屏蔽层都锈了还在跑,稳得很。也见过新布的精装修线,配了最好的转换器,三天两头丢数据。
区别在哪?不在钱多钱少,在细节有没有做到位。线选对了吗?屏蔽接地接对了吗?终端电阻加对了吗?布线避开干扰源了吗?共地线拉了吗?波特率设保守了吗?
这些问题你全部处理好了,RS485稳如老狗,一年不重启都不带丢一个包的。有一个没处理好,你调代码调出花来也白搭,物理层的毛病软件永远修不好。
干到后面我发现了一件事,RS485调不通的时候,八成不是代码的锅,是现场接线、布线、干扰这些乱七八糟的事儿。我后来排查问题的顺序变了,先拿万用表测一遍线路,确认物理层没问题了,再去翻代码。倒过来干的话,一天时间全浪费在代码上,最后一测发现是线断了,能把自己气死。