019 Modbus【协议】

概述

Modbus协议最初由Modicon公司开发出来,在1979年末该公司成为施耐德自动化部门的一部分,现在Modbus已经是工业领域全球最流行的协议。协议支持传统的RS-232、RS-422、RS-485和以太网设备。许多工业设备,包括PLC,DCS,智能仪表等都在使用Modbus协议作为他们之间的通讯标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。

Modbus有ASCII、RTU和TCP三种,其中TCP和RTU协议非常类似,只要把RTU协议的两个字节的校验码去掉,然后在RTU协议的开始加上5个0和一个6并通过TCP/IP网络协议发送出去即可。所以仅介绍一下Modbus的ASCII和RTU协议。

ASCII模式:控制器设为在Modbus网络上以ASCII(美国标准信息交换代码)模式通信,在消息中的每字节都作为两个ASCII字符传输。主要优点是字符发送的时间间隔可达到1秒而不产生错误。

RTU模式:控制器设为在Modbus网络上以RTU(远程终端单元)模式通信,在消息中的每字节按原值处理。主要优点是相对于ASCII,表达相同的信息需要较少的位数,且在相同通讯速率下具有更大的数据流量。因此通常情况下,一般工业智能仪器都采用RTU模式。

ASCII协议和RTU协议相比拥有开始和结束标记,因此在进行程序处理时能更加方便,而且由于传输的都是可见的ASCII字符,所以进行调试时就更加的直观,另外它的LRC校验也比较容易。但是因为它传输的都是可见的ASCII字符,RTU传输的数据每一个字节ASCII都要用两个字节来传输,比如RTU传输一个十六进制数0xF9,ASCII就需要传输’F’’9’的ASCII码0x39和0x46两个字节,这样它的传输的效率就比较低。所以一般来说,如果所需要传输的数据量较小可以考虑使用ASCII协议,如果所需传输的数据量比较大,最好能使用RTU协议。

019 Modbus【协议】_第1张图片
Modbus事务处理(无差错)
019 Modbus【协议】_第2张图片
Modbus事务处理(异常响应)

Modbus是一种单主站的主从通信模式,Modbus网络上只能有一个主站存在,主站在Modbus网络上没有地址,每个从站必须有唯一的地址,从站的地址范围为0 - 247,其中0为广播地址(Modbus 从站地址为 0 时会向所有从站发送广播帧,从站均不响应),从站的实际地址范围为1 - 247。Modbus RTU 使用主/从站网络,其中整个通信仅由一个主站设备触发,而从站只能响应主站的请求。主站将请求发送到一个从站地址,并且只有该地址上的从站做出响应。

传输方式

目前,Modbus可以通过下列三种通信方式实现:

1.以太网方式:对应的传输模式是MODBUS TCP,通讯介质包括5类/6类网线或光纤等;

2.异步串行口方式:对应的传输模式是MODBUS RTU、ASCII,各种通讯介质包括有线的

RS-232/422/485、光纤、无线等;

3.高速令牌传递方式:对应的传输模式是Modbus PLUS,通讯介质包括双绞线、同轴电缆等。

帧介绍

数据传送帧结构顺序是,主站和从站/从站和主站之间的数据通信从从站地址开始,接下来是功能代码, 随后传输数据,数据字段的结构取决于使用的功能代码,帧的最后传送的是校验。

019 Modbus【协议】_第3张图片
通用Modbus帧

由发送设备将 Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。 在 RTU 模式,报文帧由时长至少为3.5个字符时间的空闲间隔区分。在后续的部分,这个时间区间被称作t3.5。

019 Modbus【协议】_第4张图片
019 Modbus【协议】_第5张图片
RTU帧
019 Modbus【协议】_第6张图片

整个报文帧必须以连续的字符流发送。 如果两个字符之间的空闲间隔大于 1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。

ASCII帧

地址码

地址码为通讯传送的第一个字节。这个字节表明由用户设定地址码的从机将接收由主机发送来的信息。并且每个从机都有具有唯一的地址码,并且响应回送均以各自的地址码开始。主机发送的地址码表明将发送到的从机地址,而从机发送的地址码表明回送的从机地址。

功能码

通讯传送的第二个字节。ModBus通讯规约定义功能号为1到127(128-255 为 异常响应保留)。只利用其中的一部分功能码。作为主机请求发送,通过功能码告诉从机执行什么动作。作为从机响应,从机发送的功能码与从主机发送来的功能码一样,并表明从机已响应主机进行操作。如果从机发送的功能码的最高位为1(比如功能码大与此同时127),则表明从机没有响应操作或发送出错。

功能码中较长使用的是1、2、3、4、5、6号功能码,使用它们即可实现对下位机的数字量和模拟量的读写操作。

01读可读写数字量寄存器(线圈状态):

发送命令:

[设备地址] [命令号01] [起始寄存器地址高8位] [低8位] [读取的寄存器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]

例:[11][01][00][13][00][25][CRC低][CRC高]

意义如下:

<1>设备地址:在一个485总线上可以挂接多个设备,此处的设备地址表示想和哪一个设备通讯。例子中为想和17号(十进制的17是十六进制的11)通讯。

<2>命令号01:读取数字量的命令号固定为01。

<3>起始地址高8位、低8位:表示想读取的开关量的起始地址(起始地址为0)。比如例子中的起始地址为19。

<4>寄存器数高8位、低8位:表示从起始地址开始读多少个开关量。例子中为37个开关量。

<5>CRC校验:是从开头一直校验到此之前。在此协议的最后再作介绍。此处需要注意,CRC校验在命令中的高低字节的顺序和其他的相反。

设备响应:

[设备地址] [命令号01] [返回的字节个数][数据1][数据2]...[数据n][CRC校验的低8位] [CRC校验的高8位]

例:[11][01][05][CD][6B][B2][0E][1B][CRC低][CRC高]

意义如下:

<1>设备地址和命令号和上面的相同。

<2>返回的字节个数:表示数据的字节个数,也就是数据1,2...n中的n的值。

<3>数据1...n:由于每一个数据是一个8位的数,所以每一个数据表示8个开关量的值,每一位为0表示对应的开关断开,为1表示闭合。比如例子中,表示20号(索引号为19)开关闭合,21号断开,22闭合,23闭合,24断开,25断开,26闭合,27闭合...如果询问的开关量不是8的整倍数,那么最后一个字节的高位部分无意义,置为0。

<4>CRC校验同上。

02读只可读数字量寄存器(输入状态):

和读取线圈状态类似,只是第二个字节的命令号不再是1而是2。

03读可读写模拟量寄存器(保持寄存器):

发送命令:

[设备地址] [命令号03] [起始寄存器地址高8位] [低8位] [读取的寄存器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]

例:[11][03][00][6B][00][03][CRC低][CRC高]

意义如下:

<1>设备地址和上面的相同。

<2>命令号:读模拟量的命令号固定为03。

<3>起始地址高8位、低8位:表示想读取的模拟量的起始地址(起始地址为0)。比如例子中的起始地址为107。

<4>寄存器数高8位、低8位:表示从起始地址开始读多少个模拟量。例子中为3个模拟量。注意,在返回的信息中一个模拟量需要返回两个字节。

设备响应:

[设备地址] [命令号03] [返回的字节个数][数据1][数据2]...[数据n][CRC校验的低8位] [CRC校验的高8位]

例:[11][03][06][02][2B][00][00][00][64][CRC低][CRC高]

意义如下:

<1>设备地址和命令号和上面的相同。

<2>返回的字节个数:表示数据的字节个数,也就是数据1,2...n中的n的值。例子中返回了3个模拟量的数据,因为一个模拟量需要2个字节所以共6个字节。

<3>数据1...n:其中[数据1][数据2]分别是第1个模拟量的高8位和低8位,[数据3][数据4]是第2个模拟量的高8位和低8位,以此类推。例子中返回的值分别是555,0,100。

<4>CRC校验同上。

04读只可读模拟量寄存器(输入寄存器):

和读取保存寄存器类似,只是第二个字节的命令号不再是3而是4。

05写数字量(线圈状态):

发送命令:

[设备地址] [命令号05] [需下置的寄存器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]

例:[11][05][00][AC][FF][00][CRC低][CRC高]

意义如下:

<1>设备地址和上面的相同。

<2>命令号:写数字量的命令号固定为05。

<3>需下置的寄存器地址高8位,低8位:表明了需要下置的开关的地址。

<4>下置的数据高8位,低8位:表明需要下置的开关量的状态。例子中为把该开关闭合。注意,此处只可以是[FF][00]表示闭合[00][00]表示断开,其他数值非法。

<5>注意此命令一条只能下置一个开关量的状态。

设备响应:

如果成功把计算机发送的命令原样返回,否则不响应。

06写单个模拟量寄存器(保持寄存器):

发送命令:

[设备地址] [命令号06] [需下置的寄存器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]

例:[11][06][00][01][00][03][CRC低][CRC高]

意义如下:

<1>设备地址和上面的相同。

<2>命令号:写模拟量的命令号固定为06。

<3>需下置的寄存器地址高8位,低8位:表明了需要下置的模拟量寄存器的地址。

<4>下置的数据高8位,低8位:表明需要下置的模拟量数据。比如例子中就把1号寄存器的值设为3。

<5>注意此命令一条只能下置一个模拟量的状态。

设备响应

如果成功把计算机发送的命令原样返回,否则不响应。 

019 Modbus【协议】_第7张图片
019 Modbus【协议】_第8张图片
019 Modbus【协议】_第9张图片
019 Modbus【协议】_第10张图片


数据区

数据区是根据不同的功能码而不同。数据区可以是实际数值、设置点、主机发送给从机或从机发送给主机的地址。

LRC校验

LRC域是一个包含一个8位二进制值的字节。LRC值由传输设备来计算并放到消息中,接收设备在接收消息的过程中计算LRC,并将它和接收到消息中LRC域中的值比较,如果两值不等,说明有错误。

LRC校验比较简单,它在ASCII协议中使用,检测了消息域中除开始的冒号及结束的回车换行号外的内容。它仅仅是把每一个需要传输的数据按字节叠加后取反加1即可。

如:30 31 30 33 30 31 32 31

首先30H+31H+30H+33H+30H+31H+32H+31H=188H,然后化为2进制,得0001 1000 1000,取反得1110 0111 0111,最后加1得1110 0111 1000,化为16进制,得0E78。

其完整消息帧应为:3A 30 31 30 33 30 31 32 31 0E 78 0D。

CRC校验

CRC域是两个字节,包含一16位的二进制值。它由传输设备计算后加入到消息中。接收设备重新计算收到消息的CRC,并与接收到的CRC域中的值比较,如果两值不同,则有误。

CRC是先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。仅每个字符中的8Bit数据对CRC有效,起始位和停止位以及奇偶校验位均无效。

CRC产生过程中,每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重复8次。在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。

计算CRC值:http://www.ip33.com/crc.html

优势

modbus通讯协议是一种工业自动化总线通信协议,其标准、开发和免费等特点,支持数千种工业智能仪器仪表厂家数据通信,同时支持多种通信接口RS232、RS85、TTL、光纤和无线等方式,协议公开、格式通俗易懂,广泛应用于多种工业自动化领域,作为该领域的无线通信设备厂家——为那…通信的WCTU设备,不仅兼容Modbus通讯协议,并且可以实现多种自主加密方式.支持多种串口通信方式,并集成多路模拟量采集AD接口和IO控制接口,监护前端PLC+DTU功能,实现一体化,节约成本,灵活多用。

不足

Modbus是在1970年末为可编程逻辑控制器通信开发的,这些有限的数据类型在那个时代是可以被PLC理解的,大型二进制对象数据是不支持的。

对节点而言,没有一个标准的方法找到数据对象的描述信息,举个例子,确定一个寄存器数据是否表示一个介于30-175度之间的温度。

由于Modbus是一个主/从协议,没有办法要求设备“报告异常”(构建在以太网的TCP/IP协议之上,被称为open-mbus除外)- 主节点必须循环的询问每个节点设备,并查找数据中的变化。在带宽可能比较宝贵的应用中,这种方式在应用中消耗带宽和网络时间,例如在低速率的无线链路上。

Modbus在一个数据链路上只能处理247个地址,这种情况限制了可以连接到主控站点的设备数量(以太网TCP/IP除外)

Modbus传输在远端通讯设备之间缓冲数据的方式进行,有对通信一定是连续的限制,避免了传输中的缓冲区漏洞的问题

Modbus协议自身提供针对未经授权的命令或截取数据没有安全性。

你可能感兴趣的:(019 Modbus【协议】)