MODBUSTCPIP协议规范详细介绍
1.该规范的发展概况
原始版本1997年9⽉3⽇作为公共评论的草案。
再版1999年3⽉29⽇,即修订版1.0。
没有⼤的技术改动,仅作了补充说明。增加了附录A和B作为对⼀些常⽤执⾏问题的回应。
该Modbus/TCP规范在万维⽹上公开发⾏。它表明开发者的意愿是把它作为⼯业⾃动化领域具有互⽤性的标准。
既然MODBUS和MODBUS/TCP作为事实上的“实际”标准,⽽且很多⽣产商已经实现了它的功能,此规范主要是阐述在互连⽹上具有普遍可⽤性的基于TCP通讯协议的MODBUS报⽂的特殊编码。
2.  概述
MODBUS/TCP是简单的、中⽴⼚商的⽤于管理和控制⾃动化设备的MODBUS系列通讯协议的派⽣产品。显⽽易见,它覆盖了使⽤TCP/IP协议的 “Intranet”和“Internet”环境中MODBUS报⽂的⽤途。协议的最通⽤⽤途是为诸如PLC’s,I/O模块,以及连接其它简单域总线或I/O模块的⽹关服务的。
MODBUS/TCP协议是作为⼀种(实际的)⾃动化标准发⾏的。既然MODBUS已经⼴为⼈知,该规范只将别处没有收录的少量信息列⼊其中。然⽽,本规范⼒图阐明MODBUS中哪种功能对于普通⾃动化设备的互⽤性有价值,哪些部分是MODBUS作为可编程的协议交替⽤于PLC’s的“多余部分”。
它通过将配套报⽂类型“⼀致性等级”,区别那些普遍适⽤的和可选的,特别是那些适⽤于特殊设备如PLC’s的报⽂。
2.1 ⾯向连接
在MODBUS中,数据处理传统上是⽆国界的,使它们对由噪⾳引起的中断有⾼的抵抗⼒,⽽且在任⼀端只需要最⼩的维护信息。
编程操作,另⼀⽅⾯,期望⼀种⾯向连接的⽅法。这种⽅法对于简单变量通过唯⼀的“登录”符号完成,对于Modbus Plus变量,通过明确的“程序路径”容量来完成,⽽“程序路径”容量维持了⼀种双向连接直到被彻底击穿。
MODBUS/TCP处理两种情况。连接在⽹络协议层很容易被辨认,单⼀的连接可以⽀持多个独⽴的事务。此外,TCP允许很⼤数量的并发连接,因⽽很多情况下,在请求时重新连接或复⽤⼀条长的连接是发起者的选择。
熟悉MODBUS的开发者会感到惊讶:为什么⾯向连接TCP协议⽐⾯向数据报的UDP要应⽤⼴泛。主要原因是通过封装独⽴的“事务”在⼀个连接中,此连接可被识别,管理和取消⽽⽆须请求客户和服务器采⽤特别的动作。这就使进程具有对⽹络性能变化的适应能⼒,⽽且容许安全特⾊如防⽕墙和代理可以⽅便的添加。
类似的推理被最初的万维⽹的开发者所采⽤,他们选⽤TCP及端⼝80去实现⼀个作为单⼀事务的最⼩的环球⽹询问。
2.2 数据编码
MODBUS 采⽤“big-endian”来表⽰地址和数据对象。
这就意味着当⼀个数字表⽰的数量⼤于所传输的单⼀字节,最⼤有效字节将⾸先被发送。例如:
16bits0x1234将为0x120x34
32bits0x12345678L将为0x120x34
0x560x78
2.3参考编号的解释
MODBUS将其数据模型建⽴在⼀系列具有不同特征的表的基础之上。这四个基本表如下
l        离散输⼊单⽐特,由I/O系统提供,只读
l        离散输出单⽐特,由应⽤程序更改,读写
l        输⼊寄存器      16⽐特,数值,由I/O系统提供,只读
l        输出寄存器      16⽐特,数值,由应⽤程序更改,读写
输⼊和输出之间以及可寻址位和可寻址代码的数据对象之间的差别并不意味着任何应⽤性能的不同。如果这是我们所讨论的⽬标机械的最⾃然的解释,那么认为所有的四个基本表是相互覆盖的看法也是⾮常普通⽽完全可以接受的。
对于每⼀个基本表,协议允许单独选择65536个数据对象中的任何⼀个,⽽且对那些对象的读写操作可以跨越多个连续的数据对象,直到达到基于处理事务功能代码的数据⼤⼩限制。
这⼉没有假定数据对象代表⼀种真正邻接的数据阵列,⽽这是⼤多数简单PLC’s的解释。
“读写常⽤参考”功能代码被定义为携带32位的参考值并且能允许在“⾮常”⼤的空间⾥可以直接访问数据对象。现在没有可以利⽤这⼀特点的PLC设备。
⼀个易造成混乱的潜在来源是⽤于MODBUS功能的参考值和⽤于Modicon                                PLC’s的“寄存器值”之间的关系。由于历史原因,⽤户参考值使⽤从1开始的⼗进制数表⽰。⽽MODBUS采⽤更普通的从0开始的⽆符号整数进⾏软件数据整理分析。
于是,请求从0读取寄存器的Modbus消息将已知值返回建⽴在寄存器4:00001(存储类型4=输出寄存器,参考值00001)中的应⽤程序。
2.4隐含长度基本原则
所有的MODBUS 请求和响应都被设计成在此种⽅法下⼯作,即接收者可确认消息的完整性。对于请求和响应为固定长度的功能代码,仅发送功能代码就⾜够了。对于在请求和响应中携带不定长数据的功能代码,数据部分前将加上⼀个字节的数据统计。
当 Modbus通过TCP运送,前缀中携带附加的长度信息以便接收者识别消息的边界,甚⾄消息被分成若⼲组进⾏传输。外在的和隐含的长
3. ⼀致性等级概述
当从草稿开始定义⼀种新的协议,有可能加强编码⽅式和阐述的⼀致性。MODBUS由于其先进的特性,已经在很多地⽅得到了实施,必须避免破坏它已经存在的实施。
因此,已经存在的成套的处理类型被划分出⼀致性等级:等级0代表普遍使⽤且总体上⼀致的功能;等级2代表有⽤的功能,但带有某些特性。现存装置的不适应于互⽤性的功能也已确认。
必须注意到,将来对该标准的扩充将定义附加的功能代码来处理现存事实标准不适⽤的情形。然⽽,被提议扩充的详细资料出现在本⼿册中将会另⼈误解。通过将代码“随机的”发送或者即便是通过检查异常响应的类型来确定特别的⽬标装置是否⽀持特别的功能代码总是可能的,⽽且该⽅法将保证引⼊这些扩充的现使⽤的 MODBUS设备的连续的互⽤性。事实上,这就是当前功能代码的分级原则。
3.1等级0
这是最⼩的有⽤功能,对主站和从站来说。
读乘法寄存器 (fc 3)
写乘法寄存器 (fc 16)
3.2等级 1
这是附加的被普遍实现的和能共同使⽤的成套功能,正如前⾯介绍过的,许多从站把输⼊,输出,离散值和寄存器值作为同等的进⾏处理。
l        读线圈 (fc 1)
l        读离散输⼊ (fc 2)
l        读寄存器输⼊ (fc 4)
l        写线圈 (fc 5)
l        写单⼀寄存器 (fc 6)
l        读异常状态字 (fc 7)
此功能对于每⼀个从站系列显然具有不同的含义。
3.3等级 2
这些是需要HMI和管理等例⾏操作的数据传送功能。
l        强制型多路线圈 (fc 15)
l        读⼀般参考值 (fc 20)
该功能可以处理并发的多个请求,⽽且能接收32位的参考数值。当前的584和984PLC’s仅使⽤此功能接收类型6的参考值(扩展的寄存器⽂件)。
该功能最适于扩充以处理⼤的寄存器空间和缺少诸如“未定位”变量的参考值的数据对象。
l        写⼀般参考值 (fc 21)
此功能可以处理并发的多个请求,也可接收32位的参考数值。当前的584和984PLC’s仅使⽤此功能接收类型6的参考值(扩展的寄存器⽂件)。
该功能最适于扩充以处理⼤的寄存器空间和缺少诸如“未定位”变量的参考值的数据对象。
l        掩膜写寄存器 (fc 22)
l        读/写寄存器 (fc 23)
此功能把⼀定范围的寄存器输⼊和输出当作单⼀的处理事务。使⽤MODBUS是执⾏规则的带有I/O模块的状态影象交换的最好办法。
如此,⾼性能的通⽤的数据采集装置可以执⾏功能3,16和23,从⽽把快捷的数据规则交换(23)和执⾏特殊数据对象的需求询问或更新的能⼒结合起来(3和16)。
l        读FIFO队列 (fc 24)
⼀个有点专⽤的功能,打算将表结构的数据象FIFO(⽤到584/984上的FIN和FOUT功能模块)⼀样传送到主机。对于某种事件录⼊软件很有⽤。
3.4机器/⼚家/⽹络的特殊功能
以下所有的功能,虽然在MODBUS协议⼿册中提到,但由于它们有很强的机器依赖性,因⽽不适于互⽤性的⽬的。
l        诊断 (fc 8)
l        编程 (484) (fc 9)
l        轮询 (484) (fc 10)
l        获取通讯事件计数器值(Modbus) (fc 11)
l        获取通讯事件记录(Modbus) (fc 12)
l        编程 (584/984) (fc 13)
l        编程 (884/u84) (fc 18)
l        恢复通讯连接 (884/u84) (fc 19)
l        编程 (原理) (fc 40)
l        固件置换 (fc 125)
l        编程 (584/984) (fc 126)
l        通告本地地址 (Modbus) (fc 127)
4. 协议结构
本部分阐述了通过MODBUS/TCP⽹络携带的MODBUS请求和或响应封装的⼀般格式。必须注意到请求和响应本体(从功能代码到数据部分的末尾)的结构和其它MODBUS变量具有完全相同的版⾯格式和含义,如:
MODBUS 串⾏端⼝ - ASCII 编码
MODBUS 串⾏端⼝ - RTU (⼆进制) 编码
MODBUS PLUS ⽹络 – 数据通道
这些其它案例仅在组帧次序,检错模式和地址描述等格式有所不同。
所有的请求通过TCP从寄存器端⼝502发出。请求通常是在给定的连接以半双⼯的⽅式发送。也就是说,当单⼀连接被响应所占⽤,就不能发送其它的请求。有些装置采⽤多条TCP连接来维持⾼的传输速率。
然⽽⼀些客户端设备尝试“流⽔线式”的请求。允许服务器以这种⽅式⼯作的技术在附录A中阐述。tcpip协议中基于tcp协议的应用程序
MODBUS “从站地址”字段被单字节的“单元标识符”替换,从⽽⽤于通过⽹桥和⽹关等设备的通讯,这些设备⽤单⼀IP地址来⽀持多个独⽴的终接单元。
请求和响应带有六个字节的前缀,如下:
byte 0:    事务处理标识符 –由服务器复制 –通常为 0
byte 1:    事务处理标识符 –由服务器复制 –通常为 0
byte 2:    协议标识符= 0
byte 3:    协议标识符= 0
byte 4:    长度字段(上半部分字节) = 0 (所有的消息长度⼩于256)
byte 5:    长度字段  (下半部分字节)  = 后⾯字节的数量
byte 6:    单元标识符 (原“从站地址”)
byte 7:    MODBUS 功能代码
byte 8 on:  所需的数据
因⽽处理⽰例“以4的偏移从UI 9读1寄存器”返回5的值将是
请求:00  00  00  00  00  06  09  03  00  04  00  01
响应:00  00  00  00  00  05  09  03  02  00  05
⼀致性等级0-2的功能代码的应⽤的例⼦见后续部分
熟悉MODBUS的设计师将注意到MODBUS/TCP中不需要“CRC-16”或“LRC”检查字段。⽽是采⽤TCP/IP和链路层(以太⽹)校验和机制来校验分组交换的准确性。
5. ⼀致性等级的协议参考值
注意到在例⼦中,请求和响应列在功能代码字节的前⾯。如前所述,在MODBUS/TCP案例中有⼀个依赖传输的包含7个字节的前缀。
ref  ref  00  00  00  len  unit前⾯两个字节的“ref  ref”在服务器中没有具体的值,只是为⽅便客户端⽽从请求和响应中逐字的复制过来。单客户机通常将该值置为0。
在这个例⼦中,请求和响应的格式如下(例⼦是“读寄存器”请求,详述见后⾯部分)。
03 00 00 00 01  =>  03 02 12 34
这表⽰给前缀加上⼀个⼗六进制的串联的字节,这样,TCP连接上的整个消息将是(假设单元标识符还是09)
请求:  00 00 00 00 00 06 09 03 00 00 00 01
响应:  00 00 00 00 00 05 09 03 02 12 34
(所有的这些请求和响应通过查询Modicon Quantum PLC规范采⽤⾃动⼯具来进⾏校验。
5.1等级0指令详述
5.1.1读乘法寄存器(FC 3)
请求
Byte 0:          FC = 03
响应
Byte 0:          FC = 03
Byte 1:          响应的字节数 (B=2 x指令数)
Byte 2-(B+1):      Register values
异常
Byte 0:          FC = 83 (hex)
Byte 1:          异常代码 = 01 or 02
⽰例:
读参考值为0 (Modicon 984中为40001)时的1寄存器得到⼗六进制的值1234
03 00 00 00 01  =>  03 02 12 34
5.1.2 写乘法寄存器(FC 16)
请求
Byte 0:          FC = 10 (hex)
Byte 1-2:    参考数值
Byte 3-4:        指令数 (1-100)
Byte 5:          字节数 (B=2 x word count)
Byte 6-(B+5):      寄存器值
响应
Byte 0:          FC = 10 (hex)
Byte 1-2:        参考数值
Byte 3-4:        指令数
异常
Byte 0:          FC = 90 (hex)
Byte 1:          异常代码 = 01 or 02
⽰例:
读参考值为0(Modicon 984中为40001)时的1寄存器得到⼗六进制的值1234
10 00 00 00 01 02 12 34  =>  10 00 00 00 01
5.2等级1指令详述
5.2.1 读线圈 (FC 1)
请求
Byte 0:          FC = 01
Byte 1-2:        参考数值
Byte 3-4:        ⽐特数(1-2000)
响应
Byte 0:          FC = 01
Byte 1:          响应的字节数 (B=(⽐特数+7)/8)
Byte 2-(B+1):      ⽐特值(最⼩意义位⾸先绕线圈!)
异常
Byte 0:          FC = 81 (hex)
Byte 1:          exception code = 01 or 02
⽰例
读参考值为0 (Modicon 984中为00001)时的1线圈得到的值1
01 00 00 00 01  =>  01 01 01
注意到返回的数据的格式和big-endian体系结构不同。⽽且此请求如果调⽤乘法指令字且这些指令不以16位为界排列,那么该请求将在从站得到计算强化。
5.2.2读离散输⼊ (FC 2)
请求
Byte 3-4:        ⽐特数 (1-2000)
响应
Byte 0:          FC = 02
Byte 1:          响应的字节数 (B=(⽐特数+7)/8)
Byte 2-(B+1):      ⽐特值 (最⼩意义位⾸先绕线圈!)
异常
Byte 0:          FC = 82 (16进制)
Byte 1:          异常代码 = 01 or 02
⽰例
读参考值为0 (Modicon 984中为10001)时的1离散输⼊得到的值1
02 00 00 00 01  =>  02 01 01
注意到返回的数据的格式和big-endian体系结构不同。⽽且此请求如果调⽤乘法指令字且这些指令不以16位为界排列,那么该请求将在从站得到计算强化。
5.2.3 读输⼊寄存器 (FC 4)
请求
Byte 0:          FC = 04
Byte 1-2:        参考数值
Byte 3-4:        指令数 (1-125)
响应
Byte 0:          FC = 04
Byte 1:          响应的⽐特数 (B=2 x 指令数)
Byte 2-(B+1):      寄存器值
异常
Byte 0:          FC = 84 (hex)
Byte 1:          异常代码 = 01 or 02
⽰例
读参考值为0 (Modicon 984中为30001)时的1输⼊寄存器得到⼗六进制的值1234
04 00 00 00 01  =>  04 02 12 34
5.2.4 写线圈 (FC 5)
请求
Byte 0:          FC = 05
Byte 1-2:        参考数值
Byte 3:          = FF 打开线圈, =00 关闭线圈
Byte 4:          = 00
响应
Byte 0:          FC = 05
Byte 1-2:        参考数值
Byte 3:          = FF 打开线圈, =00 关闭线圈(回波)
Byte 4:          = 00
异常
Byte 0:          FC = 85 (16进制)
Byte 1:          异常代码 = 01 or 02
⽰例
将值1在参考值为0(Modicon 984中为00001)时写⼊1线圈
05 00 00 FF 00  =>  05 00 00 FF 00
5.2.5 写单⼀寄存器(FC 6)
请求
Byte 0:          FC = 06

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。