Modbus通信协议由Modicon公司(现已经为施耐德公司并购,成为其旗下的子品牌)于1979年发明的,是全球最早用于工业现场的总线规约。由于其免费公开发行,使用该协议的厂家无需缴纳任何费用,Modbus通信协议采用的是主从通信模式(即Master/Slave通信模式),其在分散控制方面应用极其广泛,从而使得Modbus协议在全球得到了广泛的应用。

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 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读指令对比

 
MBAP报文头
地址码
功能码
寄存器地址
寄存器数量
CRC校验
Modbus RTU
01
03
01 8E
00 04
25 DE
Modbus TCP
00 00 00 00 00 06 00
03
01 8E
00 04

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

Modbus RTU与Modbus TCP写指令对比

 
MBAP报文头
地址码
功能码
寄存器地址
寄存器数量
数据长度
正文
CRC校验
RTU
01
10
01 8E
00 01
02
00 00
A8 7E
TCP
00 00 00 00 00 09 00
10
01 8E
00 01
02
00 00

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

Modbus RTU通信协议详解以及与Modbus TCP通信协议之间的区别和联系的更多相关文章

  1. 《TCP-IP详解卷3:TCP 事务协议、HTTP、NNTP和UNIX域协议》【PDF】下载

    TCP-IP详解卷3:TCP 事务协议.HTTP.NNTP和UNIX域协议>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062539 ...

  2. SQL 中详解round(),floor(),ceiling()函数的用法和区别?

    SQL 中详解round(),floor(),ceiling()函数的用法和区别? 原创 2013年06月09日 14:00:21   摘自:http://blog.csdn.net/yueliang ...

  3. Modbus通信协议详解

    附:http://www.360doc.com/content/14/0214/13/15800361_352436989.shtml 一.Modbus 协议简介 Modbus 协议是应用于电子控制器 ...

  4. Modbus 通信协议详解

    一.Modbus 协议简介     Modbus 协议是应用于电子控制器上的一种通用语言.通过此协议,控制器相互之间.控制器经由网络(例如以太网)和其它设备之间可以通信.它已经成为一通用工业标准.有了 ...

  5. Modbus 协议图文详解

    1.概论 Modbus是一种串行通信协议,由于其协议简单易用,且没有版权要求,目前已经成为工业领域通信协议的实时标准.ModBus协议是又施耐德电气的前身Modicon公司在1979年提出的.Modb ...

  6. IIC通信协议详解

    IIC通信详解 IIC概述 IIC:两线式串行总线,它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据. 在CPU与被控IC之间.IC与IC之间进行双向传送,高速IIC总线一般可达400 ...

  7. iOS中 HTTP/Socket/TCP/IP通信协议详解

    // OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. ...

  8. http通信协议详解

    转载自:http://blog.csdn.net/gueter/article/details/1524447 引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒 ...

  9. iOS中 HTTP/Socket/TCP/IP通信协议详解 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 简单介绍: // OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 ...

随机推荐

  1. python图片爬虫 - 批量下载unsplash图片

    前言 unslpash绝对是找图的绝佳场所, 但是进网站等待图片加载真的令人捉急, 仿佛是一场拼RP的战争 然后就开始思考用爬虫帮我批量下载, 等下载完再挑选, 操作了一下不算很麻烦, 顺便也给大家提 ...

  2. IT兄弟连 HTML5教程 CSS3揭秘 CSS3属性4

    7  多列布局属性 通过CSS3,开发人员能够创建多列来对文本进行布局.在CSS2时代,对于多列布局的设计,大多采用浮动布局和绝对定位布局两种方式.浮动布局比较灵活,但是需要编写大量的附加样式代码,而 ...

  3. IT兄弟连 HTML5教程 HTML5表单 HTML表单设计2

    5  隐藏域 隐藏域不会在表单中显示.如果需要在页面之间传递重要数据,则在<input>标签中设置type属性值为“hidden”建立一个隐藏域.name和value属性是必需的,用来表示 ...

  4. easyui treegrid数据重复加载问题

    在使用easyui的时候,出现了数据重复加载的问题.如下图 关于这个问题有两种说法,第一种说法是 easyui-datagrid 类在html和js中重复定义,数据渲染时会加载两次.另一种是$(&qu ...

  5. JavaScript 引擎 V8 执行流程概述

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/t__Jqzg1rbTlsCHXKMwh6A作者:赖勇高 本文主要讲解的是V8的技术,是V8的入 ...

  6. Mybatis中返回Map

    在Mybatis中,我们通常会像下边这样用: 返回一个结果 User selectOne(User user); <select id="selectOne" paramet ...

  7. spring = servlet + 依赖管理 + 业务逻辑

    spring = servlet + 依赖管理 + 业务逻辑

  8. 基于EF的一个简单实战型分层架构

    注:此博客仅适合于刚入门的Asp.net Core初学者,仅做参考. 学了3个月的Asp.net Core,将之前一个系统(http://caijt.com/it)的PHP后端用Asp.net Cor ...

  9. centOS如何灵活管理服务进程

     1.将程序跑起来,且关闭会话时程序仍在运行. nohup node index.js & (头部加了nohup,表示在你退出帐户或关闭终端之后继续运行相应的进程;尾部的&表示在后台执 ...

  10. 剑指offer笔记面试题11----旋转数组的最小数字

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5 ...