关于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通信过程不一定准确,由于具有TCP/IP栈协议,通常在Modbus TCP通讯的上位机开发中,上位机是作为客户端,控制器作为服务器。
Modbus TCP使用基于客户端-服务器的模式,其中 客户端是发送请求的设备,服务器是响应请求的设备 。客户端发送称为"Modbus报文"的请求到服务器,服务器对请求进行解析并返回相应的数据。这种模式允许多个客户端同时与服务器通信。
-20230920
下图是关于西门子1200PLC既能做客户端又能做服务器,这需要具体情况分析
西门子1200PLC使用ModbusTCP通讯时,1200PLC可以做客户端主站,也可以做服务器从站,做客户端时主动请求连接并发送命令,做服务器时被动等待连接并反馈状态
客户端在PLC程序中使用MB_CLIENT指令,服务器在PLC程序中使用MB_SERVER指令。
- 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 9B
,0C 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口
- 利用虚拟串口软件,创建两个相互连接的虚拟串口
此处采用虚拟串口的软件,创建一对相互连接的虚拟串口,虚拟创建COM1
和COM3
联通
其他地方截到的软件全名信息
创建好后去电脑的设备管理器中去确认,可以看到COM1
和COM3
相互联通
在“串口调试助手”和“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详解1;Modbus详解2;Modbus详解3;Modbus详解4
5. 了解基础比较好的视频(发现的比较晚,本人未看,有时间了再看):
RS232、RS485和TCP上的Modbus通信(1);RS232、RS485和TCP上的Modbus通信(2);RS232、RS485和TCP上的Modbus通信(3)文章来源:https://www.toymoban.com/news/detail-535407.html
6. 下一篇将会以西门子PLC软件搭建ModbusTCP仿真环境,并通过仿真环境,介绍基础知识及模拟实际应用中写一个简单的通信读取PLC数据方法
7. 使用到的测试软件,见:Modbus通信从入门到精通中使用到的测试软件文章来源地址https://www.toymoban.com/news/detail-535407.html
到了这里,关于Modbus通信从入门到精通_1_Modbus通信基础的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!