Modbus通信从入门到精通_1_Modbus通信基础

关于Modbus通信的相关知识比较零碎,此处对查找到的知识点从理论通信协议使用方法方面进行整理。
值得学习的博文:Modbus及调试用软件介绍Modbus协议和上位机应用开发介绍

1. Modbus通信理论

1.1 Modbus通信特点

  • Modbus是一种第三方公开协议,采用主从结构,主控设备房称为Modbus Master,从设备方称为Modbus Slave。

  • Modbus物理接口可以选用串口:RS232、RS485、RS422,也可以采用以太网口。

  • 采用串口或者以太网口对应的Modbus协议是不一样的,使用串口通讯,对应的是Modbus RTU或者Modbus ASCII协议,使用网口的对应的是Modbus TCP协议。

  • Modbus通信遵循以下过程:主设备向从设备发送请求,从设备分析并处理主设备的请求,然后向主设备发送结果,如果出现任何差错,从设备都会返回一个异常的功能码。

  • Modbus工作方式是请求和应答,每一次都是主设备发送指令,可以是广播或是向特定从站的单播,从站响应指令并按要求应答或者报告异常,当主站不发送请求的时候,从站是不会自己发送数据的

  • 从站与从站之间是不能直接通信,只能主站对从站发送请求,从站响应主站的请求。

  • Modbus通信是以报文形式进行,由于Modbus协议分为Modbus RTU、Modbus ASCII协议、Modbus TCP协议也就对应有三种报文

1.2 存储区概念及范围

1.2.1 存储区概念

Modbus通信协议有4个存储区:输出线圈输入线圈输入寄存器保持寄存器(也被称为输出寄存器)

  • 线圈:对应PLC中bool量,1个字节,输入线圈相当于PLC的输入点,输出线圈相当于PLC的输出点(存放bool量)
  • 寄存器:一个寄存器占1个字长度即2个字节(存放数据)

1.2.2 存储区范围

存储区范围:5位标准地址 6位扩展地址(可能在变频器上出现)
输出线圈 代号0 00001-09999 000001-065536 可读可写:类比可以用PLC程序读写输出线圈
输入线圈 代号1 10001-19999 100001-165536 只读:类比PLC的I点,不能写
输入寄存器 代号3 30001-39999 300001-365536 只读
保持寄存器 代号4 40001-49999 400001-465536 读写

输入线圈和输入寄存器对应PLC的什么区呢?
没有什么关系

具体硬件的数据保存在输入寄存器还是保持寄存器中,需要看手册

1.3 功能码

Modbus报文中包含了Modbus功能码,功能码及含义如下所示:(因为学习资源来自于2部分,因此可能会重复)
在这里插入图片描述
在这里插入图片描述
主站想要访问从站的什么数据,就要使用对应的功能码去访问,然后再加上从站对应的站号地址,数据的起始地址,点位数量,就组成了一条Modbus报文。

1.4 Modbus通讯协议和TCP/UDP协议的区别

为了便于理解Modbus通讯协议和TCP/UDP协议的区别,关于OSI参考模型和TCP/IP参考模型的简介如下图:
在这里插入图片描述
实际上OSI七层模型中 应用层,表示层,会话层,对应的都是四层模型中的应用层,因为应用层、表示层、会话层三个层次提供的服务相差不是很大,所以都给他合并了。
而数据链路层和物理层都是归属于网络接口层,又称之为链路层。这是因为数据链路层和物理层的内容相差不多,所以在TCP/IP协议中它们被归并在网络接口层(链路层)一个层次里。

  • Modbus协议属于应用层(OSI模型第7层)协议,TCP/UDP协议属于传输层(OSI模型第4层)协议,两者层级不是并列关系。
    打个比喻,Modbus协议就像公司里的总经理,TCP/UDP协议就像公司里的轿车、商务车。某天总经理要到机场去乘飞机,他可以选择:1)自己开轿车去,2)让司机开商务车送去,3)搭的士/公交车过去。若选择1),那就是总经理-轿车的关系,Modbus TCP协议就形同这种关系。若选择3),就形同另外的Modbus RTU/ASCII协议的关系。

  • Modbus协议是一种已广泛应用于当今工业控制领域的通用通讯协议。通过此协议,控制器相互之间、或控制器经由网络(如以太网)可以和其它设备之间进行通信。Modbus协议使用的是主从通讯技术,即由主设备主动查询和操作从设备。一般将主控设备方所使用的协议称为Modbus Master,从设备方使用的协议称为Modbus Slave。典型的主设备包括工控机和工业控制器等;典型的从设备如PLC可编程控制器等。Modbus通讯物理接口可以选用串口(包括RS232和RS485),也可以选择以太网口。

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

下文将介绍Modbus TCP和Modbus RTU两种协议。

2. Modbus TCP通信协议

Modbus TCP报文格式举例如下:
在这里插入图片描述

2.1 01功能码读线圈:

在这里插入图片描述

  • 事务处理标识:00 01,相当于报文的序号,可以是任意的数字,不会影响报文的意义
  • 协议标识:默认00 00即可,也是一个没有意义的数字
  • 报文长度:固定为6,指的是报文长度这两个字节后总共有6个字节
  • 单元标识:01表示访问1号站,对应下面的"Device ID"
  • 功能码:01读线圈,使用1号功能码
  • 起始地址:从00 00开始读
  • 寄存器个数:读8个线圈

2.1.1 使用“网络调试助手”模拟Modbus TCP客户端,

在这里插入图片描述

2.1.2 使用MODSIM模拟Modbus TCP服务器

使用MODSIM来模拟Modbus TCP服务器,软件的使用参考:【工具使用】Modsim32软件使用详解ModSim基本使用(Modbus模拟器)
下图显示已经连接上:Address:0001指起始地址为1号地址即第一个线圈,Length:8是指对应有8个线圈
在这里插入图片描述
发送上面第一条指令后,返回如下:
回文格式请参考Modbus TCP通信详解及仿真第2节
在这里插入图片描述
此案例中返回如下:
在这里插入图片描述
当把第二个寄存器也改为1之后,返回的数据为03,这是16进制的,对应的二进制就是0011
在这里插入图片描述

2.2 “03”功能码读保持寄存器

在这里插入图片描述

  • 单元标识:09表示访问9号站
  • 功能码:03读保持寄存器
  • 起始地址:从00 06开始读
  • 寄存器个数:读2个寄存器

保持寄存器对应的Modbus的地址是40001开始和寄存器的对应关系如下:
在这里插入图片描述

上述报文的含义是读4007-4008寄存器,对应的服务器端可以就是如下图,设置两个寄存器的值为“00011”和“00020”(十进制的值)
在这里插入图片描述
发送报文之后得到的如下图:代表9号站回复的内容
在这里插入图片描述

2.3 “0F”功能码写多个线圈

在这里插入图片描述
写的报文和上面读的报文格式是不一样的

  • 单元标识:23表示访问十六进制23号站(即十进制35号站),对应下面的"Device ID"
  • 功能码:0F写多个线圈
  • 起始地址:从00 00开始写
  • 寄存器个数:写十六进制的10个线圈,也就是十进制的16个线圈
  • 写入数据字节数:02表示写入的数据占用2个字节
  • 写入数据:由于线圈是位元件,也就是二进制的,十六进制的FF转换为二进制1111 1111 1111 1111,也就是16位全部置为1

发送过去之后16个线圈全部置为1
在这里插入图片描述
返回报文如下:

14 32 00 00 00 06 23 0F 00 00 00 10

00 00表示访问的起始地址;00 10表示访问16位

将上面的写入的数据改为:00 02,因为Modbus报文是高字节在前,对应第2个字节开始的第2个线圈,也就是第二个字节的“0000 0010”(8位中的第二位为1),即得到服务器端得到如下:
在这里插入图片描述

2.4 “10”功能码写多个保持寄存器

在这里插入图片描述

  • 单元标识:32表示访问十六进制32号站(即十进制50号站),对应下面的"Device ID"
  • 功能码:10写多个保持寄存器
  • 起始地址:从00 00开始写
  • 寄存器个数:写十六进制的3个线圈也就是4001-4003这三个
  • 写入数据字节数:06表示写入的数据占用6个字节
  • 写入数据:0C BA 2F 0F 1D 9B0C BA写给4001,1D 9B写给4003

发送报文的结果和回复的报文内容如下图:
在这里插入图片描述
以上就是对于Modbus TCP报文格式的讲解。

3. Modbus RTU通信协议

3.1 Modbus RTU特点

ModbusRTU与ModbusASCII 在报文数据发送格式上几乎一样,但也存在一些区别,具体体现在:

  • ModbusASCII 有开始字符(:)和结束符(CR LF),可以作为一帧数据开始和结束的标志,而ModbusRTU没有这样的标志,需要用时闻间隔来判断一帧报文的开始和结束。协议规定的时间为3.5 个字符周期,就是说一帧报文开始前,必须有大于3.5 个字符周期的空闲时间,一帧报文结束后,也必须要有 3.5 个字符周期的空闲时间否则会出现粘包的情况。
    注意:针对 3.5 个字符周期,其实是一个具体时间,但是这个时间跟波特率相关,在串口通信中,1 个字符包括 1位起始位,8 位数据位(一般情况), 1位校验位上(或者没有),1位停止位(一般情况下)。因此1 个字符包括 11个位,那么3.5 个字符就是38.5 个位,波特率表示的含义是每秒传输的二进制位的个位,因此如果是 9600 波特率,3.5 个字符周期=1000/9600*38.5=4.01ms

  • 两者校验方式不同,ModbusRTU 是CRC 循环冗余校验,ModbusASCII是LCR 纵向冗余校验

  • 在 Modbus 标准中,RTU 是必须要求的,ASCII 是可选项,即作一个 Modbus 通值设备可以是支持RTU,也可以支持RTU和ASCII,但不能只支持ASII

3.2 Modbus RTU报文的格式

ModbusRTU/ASII 报文格式: 从站地址 (1byte) +功能码 (1byte) +数据(N byte) +校验 (2 byte)

对于读取:
站地址:要找谁?一个网络中每一个从站设备都需要有自己的站地址,而且不能重复
功能码:要干什么?
数据:具体要怎么干?
校验:其前面的内容的校验

下图为将会介绍的Modbus RTU报文的举例
在这里插入图片描述

3.2.1 “1”号功能码:读线圈(输出线圈)

在这里插入图片描述

  • 站地址:01,占1个字节
  • 功能码:01,占1个字节
  • 寄存器地址:寄存器的起始地址00 00,2个字节
  • 寄存器数量:00 08读取的线圈数量
  • CRC校验码:根据其前面的报文计算得到,CRC的计算方法这里不做介绍,一些串口调试助手可以自动计算得出

3.2.1.1 采用虚拟串口模拟串口硬件连接

仍然使用“Modsim”来进行模拟,利用“串口调试助手”进行模拟。硬件连接上可以有两种方式:

  • 两根USB转串口的线相连连接到同一台电脑,打开两个串口线生成的COM口,软件上连接对应的COM口
  • 利用虚拟串口软件,创建两个相互连接的虚拟串口
    此处采用虚拟串口的软件,创建一对相互连接的虚拟串口,虚拟创建COM1COM3联通
    在这里插入图片描述
    其他地方截到的软件全名信息
    在这里插入图片描述

创建好后去电脑的设备管理器中去确认,可以看到COM1COM3相互联通
在这里插入图片描述
在“串口调试助手”和“Modsim”中进行如下设置
在这里插入图片描述
此处讲解说“串口调试助手”是作为主站而“Modsim”作为从站,但我觉得是讲反了,需要后期再研究
发送上述报文之后得到的返回结果如下:
在这里插入图片描述

01 01 00 00 00 08 3D OC
01 01 01 21 91 90

返回的报文分析:
01站地址;
01功能码;
01是指读回数据21的字节计数,代表一个字节;
21返回数据,对应的二进制为0010 0001,可以看到是与Modsim中第1和第6个线圈为1是对应的,所以读取的数据没有问题;
91 90是CRC校验码,可以不用看

3.2.2 “2”号功能码:读离散量输入(输入线圈)

在这里插入图片描述
离散量输入也就是开关量输入,报文各部分含义基本上与上面的一致
发送和返回的报文内容如下图所示:
在这里插入图片描述

06 02 00 00 00 10 78 71
06 02 02 23 80 14 E8

报文返回2个字节数据,23 80,高字节在前23对应二进制0010 0011,与10001-10008位对应,80对应的二进制为1000 0000也是与10009-100016的值是对应的

3.2.3 “3”号功能码读保持寄存器

在这里插入图片描述

串口设备是不停的发设备,只需要不停接受就可以,但是Modbus协议的形式是一发一回的,发对的话就回。
在这里插入图片描述

3.2.4 “4”号功能码:读输入寄存器

在这里插入图片描述
报文各部分含义基本上与上面的一致
发送和返回的报文内容如下图所示:
在这里插入图片描述

20 04 00 00 00 06 76 B9
20 04 0C 00 0B 00 0C 00 00 00 00 00 00 0F FF 41 38

返回的报文分析:
20站地址;
04功能码;
0C是指读回数据的字节计数,代表12个字节;
一个寄存器对应2个字节即1个字,00 0B表示第一个寄存器值为十进制11、00 0C表示第二个寄存器的值为十进制的12、0F FF表示第6个寄存器的值为十进制的4095;
41 38是CRC校验码,可以不用看

3.2.5 “5”号功能码:写单个线圈

在这里插入图片描述
此处因为是单个线圈,只需要单个线圈的地址和写入的数据即可。即将第5个寄存器置为1,FF 00是置为1的意思
发送和返回的报文内容如下图所示:
在这里插入图片描述

08 05 00 04 FF 00 CD 62
08 05 00 04 FF 00 CD 62

发送及返回报文一致

3.2.6 “10H”号功能码:写多个保持寄存器(下图中是写错了)

在这里插入图片描述
发送和返回的报文内容如下图所示:
在这里插入图片描述

12 10 00 00 00 02 04 04 57 08 AE 9E B7
12 10 00 00 00 02 43 6B

以上即为Modbus RTU报文的讲解。

3.2.7 CRC校验码生成方法

利用“串口调试助手”,以1号功能码的报文为例,计算CRC校验码的方法如下图所示:
在这里插入图片描述
在实际使用中,设备之间的报文可以通过一些监视工具去监视通讯报文

以上大部分内容来自于:Modbus通信讲解

4. Modbus RTU通信实例

此部分以实际使用到Modbus的设备-温湿度传感器,并使用ModbusPoll作为主站来读取温湿度,讲解 Modbus RTU通信

4.1 Modbus的设备-温湿度传感器

温湿度传感器套装使用说明
1、温湿度传感器 (4)
2、开关电源
3、二孔插头
4、端子(一个是作为电源端子,一个是作为485端子)
5、4根1米左右的电线,一米要分成5部分,每部分是20cm
6、螺丝刀
7、485转USB转接器
调试使用:
湿度: 40001,读取的值要除以10  40001和40002是保持寄存器地址
温度: 40002,读取的值要除以10
从站地址: 42001
波特率: 42002(0位2400,1位4800,2位9600)
第一步要分别把4个模块地址分别设置为1 2 3 4

在这里插入图片描述

4.2 Modbus RTU通信方法

此处采用模拟的主站连接实际的存在
在这里插入图片描述
在这里插入图片描述
读到的值
在这里插入图片描述

Tx: 01 03 00 00 00 02 C4 0B
Rx: 01 03 04 00 49 01 29 EB AB

00 49是湿度值(实时变化,不一定和上面截图一致):0+73=73;01 29是温度值:1*256+41=297

通讯链路上全都是字节数组,上位机中可以通过字节数组来存储数据

上述部分参考链接:Modbus详解1Modbus详解2Modbus详解3Modbus详解4

5. 了解基础比较好的视频(发现的比较晚,本人未看,有时间了再看):

RS232、RS485和TCP上的Modbus通信(1)RS232、RS485和TCP上的Modbus通信(2)RS232、RS485和TCP上的Modbus通信(3)

6. 下一篇将会以西门子PLC软件搭建ModbusTCP仿真环境,并通过仿真环境,介绍基础知识及模拟实际应用中写一个简单的通信读取PLC数据方法

7. 使用到的测试软件,见:Modbus通信从入门到精通中使用到的测试软件

猜你喜欢

转载自blog.csdn.net/Dasis/article/details/131544739