1、Modbus协议简介

Modbus是一种串行通信协议,是Modicon公司于1979年为使用可编程逻辑控制器通信而发表。现在Modbus已经成为工业领域通信协议的业界标准,并且现在是工业电子设备之间常用的连接方式。

此协议支持传统的RS-232、RS-422、RS-485和以太网设备,许多工业设备,包括PLC、DCS、智能仪表等都在使用Modbus协议作为其通讯标准。

不同的设备诸如PLC,Control Panel,I/O Device等,通过不同的链路诸如RS485,TCP/IP等都可以基于Modbus协议进行通信。

如上图所示,不同类型的设备通过Modbus进行通信,交换业务信息。这里边值得一提是GateWay这种设备,在整个有线通信系统中扮演着链路层转化的工作,他可以将在以太网上跑的Modbus设备与在RS232上跑的设备互通有无。 

1. Modbus名词解释

Modbus协议中相关名词的解释:

  • 功能码:功能码在modbus协议用于表示信息帧的功能,常用的功能码有03,04,06,16等,其中03功能码的作用是读保持寄存器内容,04功能码的作用是读输入寄存器内容(输入寄存器和保持寄存器的区别看下文),06功能码的内容是预置单个保持寄存器,16功能码的内容则是预置多个保持寄存器。
  • 输入寄存器和保持寄存器:04功能码的作用就是读输入寄存器,而03功能码的作用则是读保持寄存器,很多人在看到这两个功能码的时候总是希望找到这两个功能码的区别,保持寄存器和输入寄存器到底是什么区别,modbus协议最开始是用来解决PLC的通信协议问题的,主要用于输入输出数字量信号以及模拟量信号,所谓的输入寄存器就是从模拟量信号输入引申出来的,即输入寄存器只能从模拟量信号输入端改变寄存器,而主机则不能通过下发指令改变输入寄存器的数据,而保持寄存器则是用于输出模拟量信号的,主机是可以改变寄存器数据,也就是说对于主机而言,输入寄存器是只读的,而保持寄存器是可以读写的,当主机用06,16功能码的指令去预置输入寄存器的时候,设备会返回一个代码为0x81的错误代码,即企图写只读寄存器。
  • Modbus中的数据地址格式:在Modbus协议中,经常会出现类似于3xxxx,4xxxx寄存器,这个表示的是寄存器支持的数据类型。我们用列表来说明,还有Modbus数据地址格式是从0开始,比如以下一个寄存器40009,即表示保持寄存器,寄存器地址为00 08,类似的数据地址格式经常在组态软件以及PLC系统中用到。

  • Modbus RTU/ASCII/TCP:Modbus协议最开始是用于可编程逻辑控制器(PLC)之间的通讯,由于其具有的开放性,大量的用于现场智能仪表。Modbus协议有多个变种,其中最著名的是Modbus RTU/Modbus ASCII和Modbus TCP通信协议。其中RTU/ASCII协议是基于串行口通信,而TCP协议则是基于以太网通信。
  • Modbus错误代码表:modbus有功能码,校验码,异常功能码和错误代码,其中异常功能码和错误代码非常容易混淆,一般来说异常功能码指的是某个功能码执行的时候出现的相应异常功能码,一般都是在功能码的基础上加上0x80,比如03功能码出现的异常码是0x83异常功能码,16功能码对应出现的异常功能码则是0x90,而错误代码则是表示出现错误的具体情况,比如寄存器地址不存在,不管是读还是写,如果该寄存器地址不存在的话,错误代码为02。

2. 功能码与错误码

Modbus协议主要构成是地址码/标识码,功能码,寄存器地址,数据报文等内容。由于modbus协议是请求/应答通信协议,其其中功能码主要用于表述该数据报文执行的功能,当服务器对客户机进行响应时,它使用功能码域来指示正常响应(无差错)或者异常响应(即出现某种差错),其中的modbus协议的功能码众多,在此一一列出与大家分享。

功能码表:

其中物理离散量输入和输入寄存器只能有I/O系统提供的数据类型,即只能是由I/O系统改变离散量输入和输入寄存器的数值,而上位机程序不能改变的数据类型,在数据读写上表现为只读,而内部比特或者物理线圈和内部寄存器或物理输出寄存器(保持寄存器)则是上位机应用程序可以改变的数据类型,在数据读写上表现为可读可写。

错误码:

我们以Modbus RTU协议为例,地址码为0x01,写操作0x10,寄存器地址为0x018E,CRC校验。如寄存器可读写的话,返回正常,如寄存器只读,返回异常。

  • 下发指令:01 10 01 8E 00 01 02 00 00 69 BE(向寄存器0x018E写入一个数值为0的数据)
  • 正确回应指令:01 10 01 8E 00 01 60 1E(向寄存器地址0x018E写操作一个寄存器)
  • 错误回应指令:01 90 01 8D C0(写操作非法功能,可能是向输入寄存器写数据)

2、Modbus拓扑结构与通讯方式

1. OSI模型及总线拓扑结构

所谓的OSI,就是开放式系统互联通信参考模型,简称为OSI模型。

我们知道OSI从上到下定义了七层,应用层、表达层、会话层、传输层、网络层、链路层、物理层。我们的modbus协议定义在应用层,要完成这个通信,还要使用链路层及物理层,剩余没有使用。那么关于链路层及物理层,我们需要知道,基于这两方面的限制,我们modbus串行通信的总线拓扑结构分为两种,点到点模式及总线模式。这两种模式都为主从方式,只是所允许的从站的个数不一样,当然这也是由我们所提到的物理层电气特性所限制。

总线模式下,设备接入的方式在现场应用中又有两种方式比较常见,主干-支干及菊花链方式。官方推荐菊花链方式,如非必要不要使用主干-支干方式,如果使用了也要尽可能的缩短支干线路长度,同时我们的总线两头要配有终端电阻。

2. Modbus通讯方式

Modbus协议规定了消息、数据的结构、命令和应答的方式,Modbus串行链路数据通讯采用是主从方式。在同一时刻,只有一个主节点连接于总线,一个或多个子节点连接于同一个串行总线。

Modbus通信总是由主节点发起。子节点在没有收到来自主节点的请求时,从不会发送数据。子节点之间从不会互相通信,主节点在同一时刻只会发起一个Modbus事务处理。

主节点以两种模式对子节点发出Modbus请求:

  • 单播模式:主节点以特定地址访问某个子节点,子节点接到并处理完请求后,子节点向主节点返回一个报文(一个应答)。在这种模式,一个Modbus事务处理包含 2 个报文,一个来自主节点的请求,一个来自子节点的应答。
  • 广播模式:主节点向所有的子节点发送请求。对于主节点广播的请求没有应答返回。广播请求一般用于写命令。所有设备必须接受广播模式的写功能。地址0是专门用于表示广播数据的。

我们先从主从说起,modbus通讯两方规定为“主站” 和“从站”,(enter)一条总线网络中有一个主站,跟1-247号从站,(enter)主站发出数据请求消息,从站接收到正确消息后,(enter)响应请求并回应数据给主站; 这里需要注意的是从站无法主动向主站发送数据消息,(enter)从站之间也无法进行数据通信。

还有一点是主站可向多个从站发送通信请求,而每个从站都有唯一的设备地址,并按地址识别主站发来的消息。

前面介绍了Modbus协议规定了消息、数据的结构。这里就需要提一下Modbus帧结构,研发人员需要掌握,我们工程人员也需要简单了解一下。需要注意的是地址的两种编码模式,单播模式与广播模式。

单播模式是指,主站根据不同的从站地址挨个的与从站进行数据通信,所对应的从站会对数据请求进行相对应的响应。

单播编址模式主从站响应过程时序需要说明:(enter)主站作为命令发起方,主动向指定的从设备发送命令消息帧,要求进行寄存器区的数据读取或写入,而从站被动接收主站命令,(enter)在收到主站消息帧后,首先判断设备地址,如果是发给从站本身,则根据功能代码做相关的数据处理操作,然后按功能代码不同组成数据帧或操作回应帧,(enter)回应给主站。如不是本站地址,则丢弃消息帧,继续等待主站命令帧。主站发送命令帧后,(enter)接收回应帧正确,表明通讯响应过程完成。(enter)完成后再根据所设定的周期进行准备,进行下一个请求。这里还有一个情况是,如果主站超出约定时间未收到从站的回应帧,则与从站通讯失败。

广播模式一般用到情况很少,使用的情况也都为同一厂家的同系列或同类型设备。主站发送地址为0的数据消息,从站收到后无需响应主站。此模式仅用于写功能或者发送命令、

广播编址的时序比较简单,上面我们有详细介绍单发编址时序,是类似的,简单看一下,不作详细说明。

3、Modbus报文帧与传输模式

1. Modbus帧格式

Modbus协议定义了一种独立于链路层的数据交换单元(PDU):

报文由功能码以及数据内容构成,功能码分为三类:

  1. 公共功能码:是较好地被定义的功能码,保证是唯一的,MODBUS组织可改变的,公开证明的,具有可用的一致性测试,MB IETF RFC 中证明的,包含已被定义的公共指配功能码和未来使用的未指配保留供功能码。
  2. 用户自定义功能码:两个用户定义功能码的定义范围,即65至72和100至110,用户没有 MODBUS 组织的任何批准就可以选择和实现一个功能码,不能保证被选功能码的使用是唯一的。
  3. 保留的功能码:一些公司对传统产品通常使用的功能码,并且对公共使用是无效的功能码。

作为一个Modbus设备,建议将所有共有的功能码实现,应该就能满足用户的所有业务需求,如果有自定义功能码的需求,需要从用户自定义功能码中选择未使用的实现私有的功能。

公共功能码分为三类:

  1. 为数据访问类功能码。
  2. 诊断类功能码。
  3. 其他类别功能码。

其中数据访问类为功能码的主体部分,其主要根据Modbus对数据模型的定义,分为四小类,第一种为只读的单Bit位操作,针对名为Discretes Input数据模型。第二种是可读写的单Bit位操作,针对名为Coils的数据模型。第三种为只读的16-bit字的操作,针对名为Input Registers数据模型。最后一种为读写的16-bit字的操作,针对名为Holding Registers的数据模型。

在不同总线或网络的Modbus协议映射在协议数据单元之外引入了一些附加的域。发起Modbus事务处理的客户端构造Modbus PDU,然后添加附加的域以构造适当的通信PDU。

2. Modbus传输模式

标准的Modbus主要有三种模式:

  • ASCII模式:控制器设为在Modbus网络上先转为ASCII码在通过16进制通信。这种方式的主要优点是字符发送的时间间隔可达到1秒而不产生错误。
  • RTU模式:直接发送数据转为16进制原始报文,控制器设为在Modbus网络上以RTU模式通信。这种方式的主要优点是:相对于ASCII模式,RTU模式表达相同的信息需要较少的位数,且在相同通讯速率下具有更大的数据流量。因此通常情况下,一般工业智能仪器仪表都是采用RTU模式的Modbus规约。
  • TCP/IP、UDP/IP模式:为RTU模式的延伸。走的是基于Modbus的以太网。

Modbus串行链路有两种串行传输模式被定义:RTU模式和ASCII模式。

它定义了报文域的位内容在线路上串行的传送,确定了信息如何打包为报文和解码。

Modbus 串行链路上所有设备的传输模式 (和串行口参数) 必须相同。所有设备必须必须实现RTU模式,默认设置必须为RTU模式,ASCII传输模式是选项。

1)RTU模式

当设备使用RTU(Remote Terminal Unit)模式在Modbus串行链路通信,报文中每个8位字节含有两个4位十六进制字符。这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII模式有更高的吞吐率。每个报文必须以连续的字符流传送。

RTU 模式每个字节(11位)的格式为:1个起始位,8个数据位,1个奇偶校验位,1个停止位。偶校验是要求的,其它模式(奇校验,无校验)也可以使用。默认校验模式模式必须为偶校验。使用无校验要求2个停止位。

RTU报文帧:

2)ASCII模式

当Modbus串行链路的设备被配置为使用ASCII(American Standard Code for Information Interchange) 模式通信时,报文中的每个8位字节以两个ASCII字符发送。当通信链路或者设备无法符合RTU模式的定时管理时使用该模式。

例如:字节0x5B会被编码为两个字符,0x35和0x42(ASCII编码0x35 ="5",0x42 ="B")。

ASCII模式每个字节(10位)的格式为:1个起始位,7个数据位,1个奇偶校验位,1个停止位。偶校验是要求的,其它模式(奇校验,无校验)也可以使用。默认校验模式模式必须为偶校验。使用无校验要求2个停止位。

ASCII报文帧 :

3. 功能码描述

下面以“01 (0x01)读线圈”为例描述功能码,详细的描述请参考Modbus协议。

在一个远程设备中,使用该功能码读取线圈的1至2000连续状态。请求PDU详细说明了起始地址,即指定的第一个线圈地址和线圈编号。从零开始寻址线圈,因此寻址线圈1-16为0-15。根据数据域的每个比特将响应报文中的线圈分成为一个线圈。指示状态为1=ON 和0=OFF。第一个数据字节的LSB(最低有效位)包括在询问中寻址的输出。其它线圈依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。

请求PDU:

正确响应PDU:

错误响应PDU:


4、RS-485/422总线通信协议

1. 总线技术概述

现场总线概念是由国际电工委员会(International Electrotechnical Commission简称IEC)与1984年提出,具体定义如下:现场总线是一种应用于生产现场,在现场设备和控制装置之间以及现场设备之间实行双向、串行、多节点的数字通信技术。而RS-485又称为EIA-485是由美国电子工业协议(Electronic Industries Association简称EIA)于1983年在RS-422的基础上提出,RS-232/485串口只规定了接口的电气标准,没有规定接口的插件,电缆以及使用的协议,只是OSI规范中物理层的一个标准。严格意义来讲,RS-485总线是现场总线技术的鼻祖,但是其严格意义上来讲并不是现场总线。

理解RS-485总线需要从RS-232串口开始,现在的RS-232串口基本上都是基于RS-232C标准定义的,其接口定义有DB9以及DB25两种接口定义,现在基本上都是采用DB9接口。

RS-232串口定义如下:1.载波检测,2.接收数据,3.发送数据,4.数据终端准备就绪,5.信号地,6.调制解调器就绪,7.请求发送,8.允许发送,9.振铃提示。

现在由于计算机处理能力的增强,握手之类的处理基本上交由软件来处理,只需要采用2,3,5(RXD,TXD,GND)三根线就可以正常通信。RS-232串口采用单端非差分电路平衡传输方式传输数据,收发数据线路共用接地线,也就是说其收发数据(RXD,TXD)的表示是针对地线(GND)而言的。当数据线的电平低于-3V的时候,其为逻辑“1”,高于+3V的时候,其为逻辑“0”。所以RS-232串口并不能抑制共模干扰以及共地噪音,从而决定RS-232串口的通信距离较短,并且RS-232串口只能针对点对点通信,不能支持多点组网的通信模式。

由于工业现场通信节点众多,相互之间距离较远且外部电磁环境复杂,针对工业网络通信人们需要一种采用最少的连线互联各个通信节点,并且具备一定抑制外部干扰的通信方式来完成工业现场的通信任务。针对RS-232存在的缺点,EIA提出了RS-422/485标准,其支持点对多点通信,通信速率最大可以支持110Kbps,通信距离最远可达1200米(通过增加485中继器通信距离可以延长至6000米)。​

EIA232、EIA422、EIA485技术参数:

RS-485总线由于其采用差分平衡电路,能够极大的抑制噪音以及不受节点之间的接地电平差异的影响,具有较强的抗干扰能力以及较远的传输距离。差分平衡电路相应原理如下:在RS-485总线的两条信号线路上(485+,485-)上一根导线的电压值是另外一根导线的电压取反值,接收器的输入电压为两根导线的差值,其差值的正负表示相应的逻辑“1”和“0”(485+电压低于485-,则为逻辑“1”,反之则为逻辑“0”),其接收器最小敏感度可以达到200mV。由于RS-485总线上的两条信号线传递方向相反,大小相同的电流,当噪音电压对其形成干扰的时候,往往都是同时施加于两条信号线路上,并且施加的效果一致,而由于接收器的输入电压为两根导线的差值,其在某一条导线上的噪声电压会被另外一条导线上的噪声电压相互抵消(比如485+上的电压为+1V,485-上的电压为-1V,差值为2V,当噪声电压影响他们使其电压都上升1V,那么485+的电压为+2V,485-的电压则为0V,其差值仍然为2V,这样噪声电压就被抵消了)。同样的道理,由于RS-485总线两根导线的取值是485+,485-的差值,不同节点的接地线的电平差值并不会对差分电路造成任何影响。

RS-485总线接线:485+,485-两条信号线应该在同一条双绞线中,并且互为双绞(比如采用网络作为485线路时,只能是蓝,蓝白或者绿,绿白这样连接,而不能绿,蓝),相互之间不能调换。在RS-485总线首尾各接一个120Ω电阻,成为一个60Ω并联终端电阻,当终端电阻等于电缆的特征阻抗时,可以削弱乃至消除信号的反射。RS-485连接方式可以分为半双工连接以及全双工连接,其连线的示意图如下:

半双工连接方式:

2. RS-485总线拓扑

 RS-485总线布线规范规定其必须是总线式拓扑结构,也就是要是手牵手菊花链布线方式,但是在现场实际施工过程中,现场RS-485设备的分布不会总是按照线性分布,而可能是零散的分布在不同的位置上或者是呈网格状分布,也有可能呈树形分布,在这种情况下,采用总线式拓扑结构布线不仅浪费线材,拓扑结构也更加复杂,容易造成RS-485总线系统的通信质量不稳定。一般需要借助一些相应的设备布设成星形拓扑结构或者树形拓扑结构,方便现场布线施工以及后期现场维护工作。现将RS-485总线的几种拓扑结构以图示的方式表示出来,与大家共享。

1)总线式拓扑结构

总线式拓扑结构是RS-485总线的布线规范,总线式拓扑结构其实就是一种特殊的树形拓扑结构,只不过总线式拓扑结构的分支线路距离非常短,在RS-485总线布线中,建议分支距离不要超过0.5米,一般都是建议直接手牵手菊花链的连接,不留分支,这样可以保证没有信号反射的问题。而所谓的手牵手菊花链连接方式就是:A,B,C三台RS-485设备,A设备的485+接入B设备的485+,B设备的485+再连接C设备的485+,有更多设备的话,以此类推,485-的接线方式和485+的接线方式一样。

2)星形拓扑结构

​RS-485总线支持点对多点通信方式,即一个主控485设备控制多个从控485设备,而主控设备多放置于中心位置,如果按照总线式拓扑结构布线的话,485线路需要围绕主控485设备布线,布线方式复杂且浪费线材,利用485集线器布设成星形拓扑结构则布线结构简单,施工以及维护都会非常方便。 

3)树形​拓扑结构

在现场布线情况下,RS-485设备可能分布在某个主干线的两边,如果采用手牵手的布线方式,则会来回往复的走线,形成浪费且布线结构复杂,布设成树形拓扑结构是比较合理的。树形拓扑结构域总线式拓扑结构的区别在于树形拓扑结构的分支距离比较长,RS-485总线一旦分支距离较长的话,非常容易形成信号反射,从而导致通信不稳定,利用485中继器做隔离,可以有效的保证RS-485总线通信的稳定性。

3. 一主多从通信模式 

RS-485总线技术只是规定了接口的电气标准,并没有规定RS-485接口的电缆,插件以及通信协议,只是OSI规范中物理层的一个标准,由于RS-485总线采用差分平衡传输方式,一般使用的电缆建议采用屏蔽双绞线,使得485+与485-两两双绞,外面采用屏蔽层屏蔽外部电磁干扰,但是在现场实施施工中,有人采用平行线也是可以适用于RS-485总线的电缆,只是抗干扰能力较差,传输距离不远且通信质量不稳定,一般都是建议采用屏蔽双绞线。而接口定义形式,由于RS-485总线一般都是用到485+,485-以及GND三根线,没有硬性规定接口定义形式,一般市面上多见的接口形式有RJ45接口,工业接线端子接口,DB9串口接线端子以及RJ11电话线接口等。一般而言,采用工业接线端子更为合适,因为如果需要接入终端电阻的话,采用工业接线端子是很好接入的,而且接入屏蔽双绞线也是工业接线端子更加方便。

由于RS-485总线并没有规定通信协议,有很多厂家自己推出基于RS-485总线的通信协议,其中最为著名的是由modicon公司推出的Modbus协议,该协议具有两个版本,一个是Modbus RTU和Modbus ASCII两种帧报文格式,该内容我们会在其他文章内详细描述,我们现在讨论基于RS-485总线通信的协议的一些基本原则以及相关情况。

由于RS-485总线支持点对多点通信模式,而其没有数据冲突检测解决机制,所以数据冲突的问题都是依靠主机来解决,通过主机对整个系统进行全方位的控制,避免数据冲突的产生,一般而言,由于必须通过主机进行控制以避免数据冲突,基于RS-485总线通信只能支持一主多从的通信方式,在现实生活中,老师在课堂讲课的模式其实就是一种一主多从的通信方式,下面我们按照老师课堂授课的比喻来说明RS-485总线通信协议的一些基本原则。

由于RS-485总线支持一主多从的通信模式,主机需要能够识别下位多个从机设备,所以从机设备必须具备一个在485网络中的唯一的地址码,就像班级中给学生分配学号一样,学生的姓名可能会有重复,但是学号必须是该班级内唯一的。而老师只需要叫唤学生的学号要求学生回答问题或者做相应的动作等。 同样的道理,485通信主机通过呼叫485通信从机的地址码来控制485通信从机的相关动作。

485通信网络开始通信的时候,就会对整个网络的设备进行轮询,也就是对485通信从机进行逐个的询问,确认网络中是否存在该设备以及该设备是否能够正常运转。就像老师在正式授课之前会对班级进行点名,确认是否有人缺课,一旦有人缺课做上标识以保证在课堂提问的时候不会点到缺课的学号以免浪费时间。

485通信主机下发指令是以广播形式发送,485通信从机接收到相关指令,将指令中的地址码与自己的地址码对应,发现是下发给自己的指令则立即执行相关指令,执行完相关指令之后发送相应的状态代码给485通信主机,示意其可以继续下一条指令。否则丢弃该指令,静默等待485通信主机的下一条指令。同样的道理,当老师向某个学生提问的时候,其他学生在此期间是不能出声,只有被提问的学生回答问题,当学生回答完问题之后,就说回答完毕,然后大家静待老师的下一个提问或者授课。

​一般而言,老师授课都是一个人在课堂,但是有些特殊情况是需要两个或者两个以上的老师同时在一个课堂授课,这样就需要一个协调的机制来协调多个老师的授课。而在485通信网络中,也有可能存在多个RS-485通信主机共存于同一个RS-485通信网络中,在这种情况下,深圳市国科伟业通信技术有限公司开发出相应的485共享器用于满足这些需求,485共享器分为两种,抢占式模式以及优先级模式,抢占式模式就是先到先得,就像老师在授课的时候,谁在授课的时候其他老师是不能打断他的授课的,只有在他将该段内容讲完之后,停顿一定时间之后,其他老师才可以开始自己的授课,同样的也是先到先得,谁先开口,谁就授课,直到该段内容讲完之后再重新争取控制权。优先级模式则是定义相应的优先级,比如系主任的优先级高于普通老师的优先级,即使在老师正常授课的时候,系主任说:这里我插一句,则老师的授课自动停止,等待系主任讲完之后再重新抢夺控制权(注:485共享器并不带有存储功能,只能是多个主机重新抢夺控制权,而不是原有中断485通信主机的重新接续原有的指令,原有的通信直接失败)。

​​还有就是485通信线路问题,当传输距离较远的时候或者外部干扰过大导致噪音太大,485通信信号会有一定的衰减,就像教室较大以及教室外面比较吵闹的情况,后面的学生并不能清楚的听到相关的内容,在中间增加一个485中继器,将衰减的485信号重新整形还原放大,使得距离较远的485通信从机能够识别485信号。还有就是当教室较大,可能会在教室里面产生混音,通过在教室合理放置多个喇叭,就像485总线连接为星型拓扑结构,产生了信号反射导致通信质量不稳定,使用485集线器将各条485总线相互隔离,独立驱动可以有效的解决类似问题。

4. RS-485总线现场布线问题

RS-485总线由于其支持设备广泛,设计结构简单,布线成本低廉,抗干扰能力强,在工业现场数据通信领域得到了极其广泛使用,但是在现场施工需要注意若干事项,防止出现相关问题,避免后期的维护成本增加。

​拓扑结构问题:RS-485总线规范规定,RS-485总线需要按照总线式拓扑结构布线,在总线连接上要采用菊花链手牵手方式布线,就等于是要求从主机开始,下面的从设备用RS-485总线像人与人握手相连一样连接在一起,等于是采用一条RS-485总线将所有485设备链接在一起。但是在工业现场中,相应的RS-485设备分布并不一定呈现出线性分布情况,也有可能是网格状或者散乱的分布在现场,如果采用手牵手菊花链方式连接,布线会非常复杂且耗费线材增加成本,所以很多时候人们会采用星型拓扑结构或者树形拓扑结构布线,但是不经过相应设备(星型拓扑结构需要485集线器,树形拓扑结构需要485中继器,相关拓扑结构可以参阅RS-485总线几种拓扑结构)则会出现通信不稳定的情况。所以RS-485总线布线一定需要按照手牵手菊花链方式拓扑结构连接,如果需要连接星型拓扑结构或者树形拓扑结构,则需要借助相应设备。

​RS-485总线接地问题:在RS-485总线布线规范中,要求RS-485总线单点可靠接地,也就是说整个RS-485总线有且仅有一个点接地,但是必须是可靠接地。可靠接地其实有两个意思:1.接地的地电平较为稳定,一般建议接在主机上面或者计算机的地线上。2.整条总线的地线必须保证有可靠的连接,而在现场施工情况下,这点很容易被忽略,一般而言,由于RS-485总线采用的是手牵手连接方式,一般都是将线材剪断与485设备连接(相关页面可以参考RS-485总线几种拓扑结构相关图示),而大家一般都是采用屏蔽层线路作为地线,但是在做接地的时候,大多数人都不会将屏蔽层做连接,那实际而言,屏蔽层是分成了很多段且相互之间是没有良好连接的,这样的地线接地其实可能会适得其反的。所以一旦接地就必须将地线做良好的连接且单点可靠接地,否则宁可不接地。

线材问题:在RS-485总线布线规范中,要求485+,485-两根导线要互为双绞,且需要带有屏蔽层保护信号线不被外部环境干扰。在现场施工中,由于网线使用非常广泛,很多人采用网线作为485通信线路的线材,由于网线有八根线且单根的线径较细,采用网线作为RS-485总线的线材存在一定的浪费且通信质量不能得到保障。建议采用专用的屏蔽双绞线做为RS-485线路的线材,推荐采用0.5毫米以上线径的线材。另外,需要采购纯铜的线材,因为现在市场上的线材鱼龙混杂,很多奸商利用铁铝合金外层镀铜冒充铜线出售,这些合金线材容易折断且电阻大,对于通信质量有很大的影响,先提供一个鉴别的小窍门:将线材截断之后,对着光线看,如果截断面为铜色,则应该为纯铜线,如果为银白色,那就肯定是劣质线材,建议不要采购。

​通信距离问题:RS-485总线规范标准表明,RS-485总线在通信速率110Kbps的情况下,其通信距离可以达到1200米。但是这个是在理想状态下测定的,RS-485通信距离还受总线负载情况,外部干扰情况以及线材的优劣是相关因素。通信距离与通信线材线径粗细优劣,负载数量以及通信速率成反比,当通信速率越高,负载数量越多以及通信线材越细,RS-485总线的通信距离就越短。如果需要延长RS-485总线通信距离,可以通过增加485中继器或者通过相应的设备转换为网络线路(利用串口服务器的串口转网络功能)或者光纤线路(利用光纤Modem的串口转光纤功能)进行远距离传输。

​RS-485总线负载问题:在485总线标准中,RS-485总线的负载能力是32个单位,现有的普通485芯片负载能力一般是32个,但是最新的芯片负载能力可以达到128单位,最高可以达到400单位。所以一个485网络中的485设备数量并不一定是限制在32单位之内,其网络的最大数量是由标识485设备的地址占用的字节长度有关,而485网络的单条485总线的芯片相关,但是可以通过485集线器扩展出多条485总线来增加485网络的负载数量。建议在一条485总线上的负载数量不要超过30台485设备,因为RS-485总线上的设备一旦出现问题(如短路),就有可能会导致整个485线路上的所有设备都不能正常工作,将单条总线上的设备数量减少,可以有效的降低故障率,比如假定设备无差错的概率为99.9%,当总线上有128个设备的时候,其无差错的概率为99.9%的128次方,其整条总线无差错概率为87.98%,而通过四路的485集线器将其分割为四路单独的485总线,那每条总线的无差错概率则为99.9%的32次方,其单条总线的出错概率为96.85%,通过将大的485总线进行分割,可以有效的增强485总线的稳定性。

电阻问题:RS-485总线一般都是使用屏蔽双绞线作为通信线材,由于使用的线材质量不一,有可能造成阻抗不匹配,导致数据通信不稳定。在此建议使用120欧姆电阻匹配阻抗,保证通信稳定性。120欧姆电阻的接线方式是在RS-485总线上首尾各接一个120欧姆电阻,电阻并联在485+,485-上。提请注意的是:由于并接120欧姆电阻会导致整个RS-485总线负载能力降低,只有在阻抗不匹配的情况下才考虑并接120欧姆电阻,即一般在排除其他通信不稳定的因素下,才考虑并接电阻。

5. 工业以太网技与RS-232/485串口通信技术对比

RS-232串口作为电子设备与计算机以及电子设备之间最早的通信手段现在还广泛的应用于工业控制领域,而RS-485总线作为弥补RS-232串口通信技术通信距离短,只能支持点对点数据通信等缺点产生的通信技术同样广泛的应用于工业控制领域。随着信息社会对于工业自动化的要求不断提升,以及工业自动化程度的不断加深,由于RS-232串口支持点对多点通信,通信距离小于15米,而RS-485总线技术则通信距离为1200米,由于采用一主多从的通信模式,从设备接收发送数据都需要等待控制主机的指令,而RS-485总线技术用于长距离通信的波特率不能高于110Kbps,对于大数据量并且 实时性要求高的通信任务则难以满足需求。原有的基于RS-232/485串口通信的工业控制系统越来越不能满足工业控制领域现实的需求。

随着以太网技术以及互联网在社会生活各个领域的发展,工业以太网技术现在也正在逐步的深入至工业现场控制领域,原先的工业控制网络基本上是由现场总线一统天下,现在由于以太网技术在办公系统的普及应用以及互联网技术的不断发展,工业以太网技术开始逐步的渗入到工业控制网络的信息层和控制层,而工业控制网络的设备层现在还基本上现场总线技术作为主要通信手段,所以现在工业控制网络现在还处于现场总线技术和工业以太网技术混合使用的过程当中,让这些利用现场总线技术通信的设备连接至工业以太网则非常必要,而工业控制现场领域RS-485总线设备以及RS-232串口设备具有相当的占有率,将串口设备连接至工业以太网具有相当的重要性。

通过工业以太网技术作为通信手段相比RS-232/485串口通信技术具有以下几个优势:

  1. 以太网设备的配置更加灵活方便,多个RS-232串口设备与计算机通信一般都是在计算机PCI插槽上通过多串口卡或者通过USB串口连接USB转串口集线器来实现RS-232串口的扩展,每个计算机的PCI插槽或者USB接口都是有一定的数量限制,从而使得与计算机通信的RS-232串口设备的数量受到相应的限制。而RS-485总线虽然布线简单,负载设备多,通信距离可以达到1200米,但是其布线必须采用手牵手菊花链拓扑结构,在RS-485总线上增加设备需要将线路布设过去或者通过增加485中继器或者485集线器来解决布线问题,而以太网则不同,只要是有网络信息口的地方,就可以直接将相关的以太网设备连线接入以太网,而且接入设备的数量基本上是没有限制的。
  2. 支持热插拔工作,能够在系统工作的时候配置相关设备,无需停止系统工作。比如计算机需要增加多串口卡以扩充RS-232串口数量的时候,需要将计算机停机并打开机箱才可以增加多串口卡,同样的道理,在RS-485总线上添加相应的485设备的时候,也是需要将线路中断才可以增加相应的设备,而在以太网上增加相应的以太网设备,只需要在附近的信息口上接上网线就可以,再通过计算机上的相关软件进行配置就可以正常工作。
  3. ​简单易用,后期的维护方便简捷,不管是RS-232设备还是RS-485总线通信一般都是只与单台计算机进行通信,很难形成双服务器冗余热备份系统,而在以太网上可以非常容易的配置双服务器冗余热备份系统。同样的道理,基于RS-232串口通信或基于RS-485总线通信,不能形成冗余链路,一旦出现问题就可能整个系统崩溃,特别是RS-485总线,在RS-485总线上出现问题(比如短路),很容易导致整个系统不能使用,而且在RS-485总线上查找故障点非常困难,需要一个一个的去排查。而基于工业以太网作为通信手段则可以避免类似问题,采用工业以太网交换机布设环形冗余链路的工业网络,一旦某个链路出现问题,可以在20ms之内自愈恢复并及时告警提示维护。
  4. 高扩展性和高扩充性,非常适应弹性布线。前文所述,以太网设备使用热插拔工作以及配置灵活方便,采用以太网作为通信手段可以没有距离上和数量上的限制,RS-485总线通信距离为1200米,可以通过增加485中继器或者通过光纤modem转换为光信号通过光纤传输从而达到延长通信距离的作用,但是传输距离总是有一定的限制,而通过以太网可以连接至互联网,通过互联网可以在世界任何一个有网络连接的地方进行数据交换,同样的,RS-485总线长距离通信的最大速率为110Kbps,而现在快速以太网(100M)已经基本普及,千兆以太网则正在逐步进入工业控制领域,所以以太网的通信容量以及在以太网上通信的设备数量基本上没有任何限制。
  5. 通过以太网通信实现真正的“管控一体化”,随着工业控制自动化程度以及办公系统自动化程度的加深,现在提出了工业控制领域“管控一体化”的目标,也就是说工业控制系统与办公自动化系统能够紧密结合,信息互通有无实现无缝对接。由于现在办公系统都是基于以太网进行数据交换,所有的软件都是基于以太网运行,与以太网设备通信无需作任何修改,可以直接与之通信,能够快速的将工业控制网络中的以太网设备的相关数据整合进办公自动化系统。

​让串口设备具备以太网接口可以通过两个方案来实现,一个是通过采用外挂的串口服务器来实现串口转网络功能,深圳市国科伟业通信技术有限公司的N-3000型串口服务器向上提供一个以太网接口与以太网连接,向下提供一个RS-232/485/422串口与串口设备连接,提供串口数据信号与以太网数据信号的双向透明传输,使得串口设备立即具备以太网接口连接网络通信。另一个是通过嵌入式的串口网桥来实现串口设备到以太网设备的升级换代,N-4000D型串口网桥提供TTL转TCP的功能,将串口设备的TTL电平直接引出以太网接口,使得设备的通信接口由串口升级为以太网接口。

5、Modbus RTU串行链路通信

1. 循环冗余校验编码(CRC校验码)

计算机数据通信中,由于干扰等各种内外因素,数据出现差错不可避免,在数据通信中需要对数据进行差错检测。实现差错检测的基本原理是:发送方在发送数据的基础上生产某些编码,然后将校验编码附加在数据后面一起发送,接收方在收到数据和校验码之后,用校验码对数据进行校验,确认传输的数据是否正确。

差错检测技术的核心是校验编码,常用的校验有奇偶校验,恒比较校验和循环冗余校验编码三种。

  1. 奇偶校验:对要发送的格式报文中的数字“1”码元个数统计,采用奇偶校验的时候,通过添加一个码元使的报文中的“1”为奇数(奇校验)或者偶数(偶校验),如果在接收的时候发现报文中的“1”码元数不符合奇偶校验的规定,就判定数据出错。奇偶校验存在一定的缺陷:当出错码元个数为奇数的时候才有效,如果为偶数的话,奇偶校验就不能检测出来。ISO规定,在同步传输系统中,采用奇校验,在异步传输系统中,采用偶校验。
  2. 恒比码:在通信时不是原码传送,而是对待发送的数据编码,使之编码之后的每一个字节中,“1”与“0”的个数之比保持恒定,称之为恒比码,该编码用于国内电报通信。恒比码纠错能力稍强于奇偶校验,当码组中出现奇数个数的差错时,破坏了“0”与“1”的恒比关系,能够被检测出来,当出现偶数个数的差错时,只要不是非置换型的两个码元错误,即两数个“0”全错成“1”,或者相反,都可以检测出来,但是出现置换型的错误,即某个位置的“1”出错为“0”,而另外一个位置的“0”出错为“1”,恒比码则不能检测出来。
  3. 循环冗余校验码:简称CRC码,CRC校验码是一种高性能的检错码,具有检错能力强,实现简单容易,良好的代数结构等特点,比如奇偶校验和恒比码不能检测出来的置换型错误,CRC校验能够很好的检测出来。

2. Modbus RTU 与 Modbus TCP 通信协议区别

Modbus通信协议具有多个变种,其具有支持串口(主要是RS-485总线),以太网多个版本,其中最著名的是Modbus RTU,Modbus ASCII和Modbus TCP三种。其中Modbus RTU与Modbus ASCII均为支持RS-485总线的通信协议,其中Modbus RTU由于其采用二进制表现形式以及紧凑数据结构,通信效率较高,应用比较广泛。而Modbus ASCII由于采用ASCII码传输,并且利用特殊字符作为其字节的开始与结束标识,其传输效率要远远低于Modbus RTU协议,一般只有在通信数据量较小的情况下才考虑使用Modbus ASCII通信协议,在工业现场一般都是采用Modbus RTU协议,一般而言,大家说的基于串口通信的Modbus通信协议都是指Modbus RTU通信协议。

Modbus TCP协议则是在RTU协议上加一个MBAP报文头,由于TCP是基于可靠连接的服务,RTU协议中的CRC校验码就不再需要,所以在Modbus TCP协议中是没有CRC校验码,用一句比较通俗的话说就是:Modbus TCP协议就是Modbus RTU协议在前面加上五个0以及一个6,然后去掉两个CRC校验码字节就OK.虽然这句话说得不是特别准确,但是也基本上把RTU与TCP之间的区别说得比较清楚了。

​RTU协议中的指令由地址码(一个字节),功能码(一个字节),起始地址(两个字节),数据(N个字节),校验码(两个字节)五个部分组成,其中数据又由数据长度(两个字节,表示的是寄存器个数,假定内容为M)和数据正文(M乘以2个字节)组成,而RTU协议是采用3.5个字节的空闲时间作为指令的起始和结束,一般而言,只有当从机返回数据或者主机写操作的时候,才会有数据正文,而其他时候比如主机读操作指令的时候,没有数据正文,只需要数据长度即可。(这里讨论只涉及寄存器的读写,其他比如线圈的读写指令我们暂时不涉及)。在此我们通过两个指令(0x03H:读多个寄存器指令以及0x10H:写多个寄存器指令)来解释Modbus RTU协议。在此我们使用的RTU设备是深圳市国科伟业通信技术有限公司的ND-1084型485总线I/O模块。

ND-1084型485总线I/O模块采用RS-485总线通信,支持四路开关量输出以及八路开关量输入,我们只讲述读取开关量输出的状态以及通过写指令控制开关量的输出。其中储存开关量输出状态的四个寄存器分别:0x18E,0x18F,0x190,0x191。在此我们假设模块的地址为默认的0x01,当我们要去读取开关量输出对应的四个寄存器的状态的时候,我们下发的十六进制的指令为:“01 03 01 8E 00 04 25 DE”,其中“01”为模块的地址码,“03”为功能码,即表示读寄存器,“01 8E”为寄存器地址,即从该寄存器地址开始读取数据,“00 04”则表示读取4个寄存器,而“25 DE”则为前面“01 03 01 8E 00 04”的CRC校验码,该数值通过CRC16校验算法计算出来的,我们会在其他文章中阐述。该指令的完整解读就是,在地址码为“01”的模块中,从“01 8E”寄存器开始,读取4个寄存器的数据返回至主机。在此,我们可以看到,读取指令中并没有什么数据正文,因为它只是读取相应数量的寄存器,并不需要数据正文,而写操作指令则相反,我们会在后面讲到。

模块返回的指令是:“01 03 08 00 01 00 01 00 01 00 01 28 D7”,返回的指令内容解读就是:“01”表示模块的地址码,“03”表示该指令是读操作返回的指令,“08”表示数据长度,在此表示的是8个字节数据正文(即4个寄存器,每个寄存器两个字节表示),“00 01 00 01 00 01 00 01”是数据正文,表示四个寄存器的状态,“28 D7”就是CRC16校验码。

同样的当我们执行写操作的是,我们举例写第一个开关量输出,即寄存器“0x18E”,主机下发的指令为:“01 10 01 8e 00 01 02 00 00 A8 7E”,该指令的解读就是:“01”表示模块的地址,“10”表示该指令为写寄存器,“01 8E”表示从该寄存器地址开始执行写操作指令“00 01”表示写多少个寄存器,在此为写1个寄存器,“02”表示数据长度,表示数据长度为两个字节,“00 00”表示写入寄存器的数据,在此表示连通,“A8 7E”为CRC校验码。模块返回的指令和读取寄存器的返回的指令类似。

前文所述,Modbus TCP协议是在RTU协议前面添加MBAP报文头,共七个字节长度,其分别的意义是:1.传输标志,两个字节长度,标志Modbus询问/应答的传输,一般默认是00 00。2.协议标志,两个字节长度,0表示是Modbus,1表示UNI-TE协议,一般默认也是00 00。3.后续字节计数,两个字节长度,其实际意义就是后面的字节长度,具体情况详见下文。4.单元标志,一个字节长度,一般默认为00,单元标志对应于Modbus RTU协议中的地址码,当RTU与TCP之间进行协议转换的时候,特别是Modbus网关转换协议的时候,在TCP协议中,该数据就是对应RTU协议中的地址码,具体情况详见下文。

通过上面的描述我们差不多能够理解Modbus RTU协议,我们再说说Modbus TCP通信协议,前面就已经说过TCP协议就是在RTU协议的基础上去掉校验码以及加上五个0和一个6,当是读取相关寄存器的时候,该说法是没有错的,比如上文的“01 03 01 8E 00 04 25 DE”读取指令,用TCP协议来表述的话,指令是“00 00 00 00 00 06 00 03 01 8E 00 04”,由于TCP是基于TCP连接的,不存在所谓的地址码,所以06后面一般都是“00”(当其作为Modbus网关服务器挂接多个RTU设备的时候,数值从01-FF).即“00 03 01 8E 00 04”对应的是RTU中去掉校验码的指令,前面则是五个0以及一个6。其中6表示的是数据长度,即“00 03 01 8E 00 04”有6个字节长度。而当其为写操作指令的时候,其指令是“00 00 00 00 00 09 01 10 01 8e 00 01 02 00 00”,其中“00 09”表示后面有9个字节。

Modbus RTU与Modbus TCP读指令对比:​

指令的涵义:从地址码为01(TCP协议单元标志为00)的模块0x18E(01 8E)寄存器地址开始读(03)四个(00 04)寄存器。

Modbus RTU与Modbus TCP写指令对比:

指令的涵义:从地址码为01(TCP协议单元标志为00)的模块0x18E(01 8E)寄存器地址开始写(10)一个(00 01)寄存器,具体数据长度为2个字节(02),数据正文内容为00 00(00 00)。 

3. Modbus RTU 与 Modbus ASCII 通信协议区别

Modbus基于串行通信存在两种模式:Modbus RTU与Modbus ASCII模式,不管是RTU模式还是ASCII模式,Modbus信息都以帧的方式传输,每个信息帧有确定的起始点和结束点,使接收设备在信息的起点开始读地址,并确定要寻址的设备 (主机广播时对全部设备),以及信息传输的结束时间。并且可检测部分信息,错误可作为一种结果设定。

Modbus RTU通信格式:

  1. 站号:1-247
  2. 波特率:4800 9600 19200 38400 115200
  3. 校验:奇校验(ODD ) 偶校验( EVEN) 无校验(NONE)
  4. 数据位:7位 8位
  5. 停止位:1 2

波特率越高,通信速度越快,但是出错几率越大。

PLC的校验、数据位、停止位要与通讯设备配置一样才能通信。

数据存储地址与寄存器地址:

0~9999             线圈              类似于Q点      可读可写    1个bit

10001~19999  输入             类似于I点       只读           1个bit

30001~39999  输入寄存器   类似于AI       只读            16bit

40001~49999  保持寄存器                        可读可写      16bit

工控前三种类型很少使用,基本使用的是保持寄存器。

保持寄存器中的数据是没有类型的,希望保持寄存器是什么就可以是什么类型,使用的时候要和设备中的类型保持一致。如果是变频器设备,40001是变频器设备,查看设备说明文档查看40001是什么数据类型,然后保证和PLC中的数据类型一致,然后读回去转成相应的类型就是对应的数据。

RTU模式与ASCII模式之间的区别就在于:

1)开始和结束的标志不同

RTU模式的开始和结束的标志是传输3.5字节所需要的空闲时间,假设串口通信速率为9600bps,传输一个字节所需的时间为一个毫秒左右(8/9600即/1200秒),3.5个字节的空闲时间大概就是3-4个毫秒,即当波特率为9600bps时,RTU传输空闲时间为6-8毫秒(上一个 信息帧结束空闲时间和信息帧开始空闲时间)即可开始一个新的信息帧。而ASCII模式则是采用固定的ASCII字符表示开始(:,冒号,十六进制为3AH)和结束的(CRLF,回车-换行键,十六进制为0D和0AH)。

2)校验模式不同

RTU模式采用CRC校验码,而ASCII模式则采用LRC校验码,相对来说LRC校验码更加简单易懂。LRC校验码就是将信息帧中除开始结束符(:和回车换行)之外的所有数据按字节叠加取反加1即可。

LRC校验码代码如下;

BYTE GetCheckCode(const char*pSendBuf,int nEnd)//获得LRC校验码
 {
 BYTE byLrc=0;char pBuf[4];int nData=0;
 for(i=1;i<end;i+=2)
  {
  pBuf[0]=pSendBuf[i];
  pBuf[1]=pSendBuf[i+1];
  pBuf[2]='\0';
  ssanf(pBuf"%X",&nData;byLrc+=nData);
  }
  bLrc=~bLrc;
  bLrc++;
 }

CRC校验码则是每个八位字符都单独和寄存器内容相或(OR),结果向最低有效为移动,最高有效位以0填充,LSB为1,寄存器和预置的值或一下,LSB为0,则不进行,整个过程重复8次,最后一位完成后,下一个8位字节与寄存器的当前值相或,最终寄存器的值就是CRC值

WORD GetCheckCode(const char *pSendBuf,int nEnd)//获取CRC校验码
{
WORD wCrc=WORD(0xFFFF);
 for(inti=0;i<nEnd;i++)
  {
  wCrc^=WORD(BYTE(pSendBuf[i]));
  for(int j=0;j<8;j++)
   {
   if(wCrc&1)
    {
    wCrc>>=1;
    wCrc^=0xA001;
    }
   }
   else
   {
   wCrc>>=1;
   }
  }
return wCrc;
}

3)RTU模式的传输效率高于ASCII模式

ASCII模式不但需要添加开始结束标志,还需要将十六进制数据转换为ASCII码,比如十六进制0x25转换为ASCII字符则为0x32,0x35,ASCII的表述效率只是RTU表述的一半。

RTU模式指令转换为ASCII模式指令:1.将CRC校验码去掉。2.将所有对应的字节转换为对应的两个字节的ASCII字符。3.加上起始标识和结束标识,并计算LRC校验码加上。

6、Modbus RTU串口通信实验

1. 硬件连线

我采用的是RS485串口通信,两线制连接,通信协议采用Modbus RTU。硬件连接就是将RS485网络上的设备并联在一起。这种接线方式为总线式拓朴结构在同一总线上最多可以挂接32个结点。

Modbus RTU接线:

PLC正接设备的正,PLC负接设备的负,屏蔽层接地。现场干扰大要接地,实际工程场景通信线和动力线分开拉线,最好通信走低压线槽,受到干扰小一点。

设备只要满足Mdobus  RTU通信的设备都可以。

Modbus RTU 接线PLC 1200

1200 PLC中自带的485模块,西门子的A是负,B是正与设备连接。     

PLC接线:

设备接线:

485接口的SG+和SG-就是设备的正和负,和PLC的正负对上就可以让PLC与设备通信了。

2. Modbus RTU通信模拟器

使用串口时Connect这里定义的是笔记本电脑与从设备连接使用的串口。具体是COM几口可以在我的电脑-->属性-->设备管理器中查找,没有串口的电脑(现在电脑一般都没有串口,可以购买USB转232(485)来解决,工程师必备工具之一)。

需要两个软件:

  • Modbus Poll:Modbus主站软件;
  • Modbus Slave:Modbus从站仿真软件;

手里没有其他设备,只有一台PLC想实现主站与从站通信,可以使用一台电脑。插一个USB 485 串口线仿真从站,连接PLC进行数据读取,进行调试。

USB转485串口通信线缆:

线缆的芯片推荐PL2302或者FT232芯片,这两个芯片几乎所有设备都满足,而有的芯片像CH340某些设备没法通信的。

PLC做主站读取/写入数据时:

假设我们需要通过Modbus RTU协议控制一台变频器,并且读取一些实时运行数据。

  1. 通信线缆检查;
  2. 将电脑连接上变频器,用Modscan读取/写入变频器参数(主要为了测试通信参数以及寄存器地址是否正确);
  3. 当1和2测试完毕以后,再进行PLC与变频器连线测试;

PLC为什么连接不上变频器?

可能原因是不是PLC程序存在问题,哪些参数配置有问题。

PLC做从站时:

假设我们需要通过Modbus RTU协议共享PLC数据,或者是其他设备需要通过Modbus RTU控制我们的PLC。PLC做为从站,其他设备主动连接读取或写入数据来控制PLC。

  1. 在PLC中设定Modbus RTU通信参数,并且在PLC中编写Modbus从站程序;
  2. 使用Modscan+usb转485通信线缆连接PLC,并测试Modbus从站程序是否正确;
  3. 第三方设备使用Modbus rtu访问我们的PLC;

第三方设备为什么连接不上PLC?

可能原因是第三方设备存在问题,因为已经可以访问到PLC从站程序了。

Modbus RTU设备连接:

硬件连接:

仿真软件仿真一个RTU从站,PLC做为主站,读取或者写入从站的数据。

3. 主/从站通信模拟

分别打开Modbus Poll与Modbus Slave,分别点开Connection中选择Connect,选择串口模式,并配置两端的串口参数一致,分别点击OK。

参数设置: 

  • Baud(波特率):9600(默认为9600,需要根据从设备串口设置,两边保持一致);
  • Word(数据位):8(默认为8,需要根据从设备串口设置,两边保持一致);
  • Parit(奇偶校验):NONE(默认为没有奇偶校验,需要根据从设备串口设置,两边保持一致);
  • Stop(停止位):1(默认为1,需要根据从设备串口设置,两边保持一致);

选择Modbus Slave中的Setup,点击Slave Definition,配置Slave相关的参数,例如地址,支持的功能码,存储单位起始地址,以及存储数量,并修改寄存器地址方便看结果,如下图:

                     

然后选择Modbus Poll,点开Set up 并点击Read/Write Definition,配置从站地址,以及读取寄存器的功能码以及相关的参数,配置完成之后,点击Read/Write Once,完成一次读取寄存器操作,能够看到Master这里的寄存器值与Slave变成了一致。

如果想要看具体发送的协议内容,在Modbus Poll中的Display中点开Communication Traffic,就能看到具体的协议交互内容,对比文档Modbus_Application_Protocol_V1_1b3就能解析发送与回复的报文内容,截图如下: 

7、问题排查

在我们实际应用中经常会碰到通讯错误及失败的情况,我接下来介绍一下modbus的错误检测、响应及时序。知道这些,有助于准确排查问题。

错误一般会有这么三种情况,在字符层存在奇偶检验错误;在消息层存在校验错误,这一帧数据不完整或者存在粘包或者帧数据本身错误。在数据层存在各种错误,如无效的功能码,无效的数据地址等。

对于错误的反馈,从站检测到一个错误时,不会处理请求也不会提供响应,主站那边等待超时后会进行重新发送或者提示错误。

主站检测到一个错误时,不会处理此错误请求,然后进行重新向从站请求或提示错误。

1. 硬件连接出现的问题:A,B线接错

RS485连接有交叉连接和直连的区别。直连就是RS485 A接A,B接B。而交叉连接就是RS485 A接B,B接A。之所以有这种区分,是不同厂家对于信号线的正负定义不同。

RS485接口由两根线组成:信号正(+)和信号负(-)。通常,信号正(+)被称为A线,信号负(-)被称为B线。但有例外,比如,西门子产品中,RS485中的B线是信号正(+),A线是信号负(-),要注意区分。

西门子PLC与其他设备通过RS485连接,通常都是交叉连接的,在我知晓这一点之前,浪费了不少时间排查通信故障。

解决方法:

  1. 交换A,B线连接,看问题是否解决
  2. 如果问题没有解决,就采用Modbus主站/从站设备模拟工具来检查发送或收到的信号是否正常。

以Moudus poll为例子,设定连接参数:

设定从站地址,功能,数量:

设备的通信记录。可用来观察发送和收到的未经过解析处理的信息。 

2. 参数设置出现的问题

检查硬件连接没有问题之后,就检查参数设置,例如波特率,数据位位数,数据校验方式,停止位位数,通信设备地址,寄存器地址,长度,读写方式。

  1. 确认通信设备地址,一般查询手册里出厂的默认设备地址。
  2. 寄存器地址注意转换。寄存器地址从0开始,而PLC地址从1开始,十进制,并且在最高位需要加一个代表寄存器属性的数值。例如读取保持寄存器,手册给出的寄存器地址是0(十进制),那么对应的PLC地址是40001(十进制),首位的4代表这是保持寄存器。例如读取保持寄存器,手册给出的0x3000的寄存器地址,那么对应的PLC地址是412289(十进制)。总结下来就是:转换为十进制,加一,加前缀。
  3. 注意功能码的选择,写单寄存器和写多重存储器的功能码是不同的。而西门子的Modbus库模块是自动根据数据长度选择写单存储器和多重存储器的功能码,但是也会碰到例外情况。我这次项目就遇到一个设备,明明要写的寄存器数量只有1,但是偏偏功能码要求0x10(写多重存储器),PLC按照写单存储器发送的命令它不接受,必须用0x10的功能码来写单寄存器。后来检查了一下,那个地址后面连着的一个寄存器它不使用,就将写寄存器的数量改为2,修改了一下发送的数据,解决了这个问题。

3. Modbus编程出现的问题

我是用西门子Smart 200 PLC的Modbus RTU库来编程的。关于编程出现的常见问题和解决方法可以查阅S7-200 SMART PLUS,里面有详细的例子和说明。可以查看错误代码,确定可能的错误原因,常见的错误代码6是同时激活了多条Modbus_MSG指令导致的,建议按照示例来写,不容易出错。如果是错误代码3,建议检查硬件和参数设置,参考前两节。

另外,设置的等待时间不要太短,时间太短的话从站来不及相应,也会出错。

4. 读取到的数据转化

PLC读取到的数据如果乱码,那可能是需要转换字节序,需要查看厂家对于设备字节序的设置。例如这次项目里的外设1,读取连着两个寄存器里的浮点数,读取到的数据必须前后两个字调换一下位置,才是正确的浮点数格式。而这次项目里的外设2,也是读取两个连着的寄存器里的浮点数,读取到的数据必须将4个字节的顺序颠倒一下,才是正确的浮点数格式。

建议遇到这种情况,查询手册看有没有说明,或者是看有没有寄存器存放常数,读取寄存器内的常数,和这个常数转化成的HEX码比较一下顺序,或者就换着顺序试试看能不能读出正常的值。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐