modbus-TCP协议详解

news2024/11/27 11:46:00

modbus-TCP协议详解

1996年施耐德公司推出基于以太网TCP/IP的modbus协议:modbus-TCP。

MODBUS-TCP使MODBUS-RTU协议运行于以太网,MODBUS-TCP使用TCP/IP以太网在站点间传送MODBUS报文,MODBUS-TCP结合了以太网物理网络和网络标准TCP/IP以及以MODBUS作为应用协议标准的数据表示方法。MODBUS-TCP通信报文包在以太网TCP/IP数据包中。与传统的串口方式,MODBUS-TCP插入一个标准的MODBUS报文到TCP报文中,不再带有数据校验和地址。

MODBUS报文解析

| MBAP Header | Function code | Data |
| Header | PDU |

MBAP header包含下面几个部分:

  • Transaction ID
  • Protocol ID
  • Length
  • UnitID
id名称长度说明
1Transaction ID 事务处理标识2字节报文的序列号,一般每次通讯加1,用于区别不同的报文
2Protocol ID 协议标识2字节00 00 代表modbus-Tcp
3Length2字节Unit长度 + PDU的长度
4UnitID单元标识符1

下面的这一串MBAP header|00 01| 00 00|00 06| 01 |, 其含义如下:

事务标识为1,协议是modbus-tcp协议,数据长度是:6,从站号是1。

需要注意的是MODBUS协议是一个大端的协议,前两个byte 00 01代表0x1 , 因此Transaction ID=1。而长度字段00 06代表0x6, 即UnitID和PDU的长度总和为6。

PDU部分相对复杂一些,主要是对一些寄存器进行读写操作。

modbus的操作对象有四种:线圈寄存器离散输入寄存器输入寄存器保持寄存器

寄存器种类数据类型访问类型功能码
线圈寄存器bit读写01H 05H 0FH
离散输入寄存器bit只读02H
输入寄存器2 bytes(word)只读04H
保持寄存器2 bytes(word)读写03H 06H 10H

线圈寄存器和离散输入寄存器是以bit为单位的寄存器,只能存储开关量,线圈寄存器可读可写,而离散输入寄存器只可读。

输入寄存器和保持寄存器以为2个byte为单位的寄存器,可以存储离散的变量, 保持寄存器可读可写, 输入寄存器只读。

常用的功能码作用如下:

功能码功能
0x01读单个或者多个线圈寄存器
0x02读离散量输入寄存器
0x03读保持寄存器
0x04读输入寄存器
0x05写单个线圈寄存器
0x06写单个保持寄存器
0x10写多个保持寄存器
0x0F写多个线圈寄存器

常用功能码详解

功能码0x1:读线圈寄存器

每个线圈寄存器可以存储一个bit的信息, 功能码0x01就是用于读取slave中线圈寄存器的状态,可以是单个线圈寄存器,也可以是多个连续的线圈寄存器

发送报文

发送报文由下面几个部分组成,总共12字节:

MBAP header(7字节) + 功能码(1字节) + 线圈寄存器起始地址的高位(1字节) + 线圈寄存器起始地址的低位(1字节) + 线圈寄存器数量的高位(1字节) + 线圈寄存器数量的低位(1字节)

下面是一个用Modbus-Poll和Modbus-Slave测试的实际的例子,其含义是读取线圈寄存器的起始地址是0x0, 读取数量为 0x0a(十进制10)个。

0x1-request

MBAP header功能码起始地址高字节起始地址低字节寄存器数量的高位寄存器数量的低位
01 66 00 00 00 06 01010000000a

其中:

TransanctionID = 358, Length = 6。

功能码为0x1,代表读取线圈寄存器。

读取的线圈寄存器的起始地址为0。

读取的线圈寄存器的数量为0xa(十进制10)个。

响应报文

响应报文的长度不是固定的,长度和用户请求的数据长度有关,由下面几个部分组成:

MBAP header(7字节) + 功能码(1字节) + 线圈寄存器的值

下面是一个实际的响应报文的内容:

0x1-request

MBAP header功能码字节数请求的数据1请求的数据2
01 66 00 00 00 05 0101022102

返回的第一个字节21,转化为二进制为00100001, 其中bit0代表00寄存器,bit7代表07寄存器。

0x70x60x50x40x30x20x10x0
00100001

返回的第二个字节02,转化为二进制为00000010, 其中bit0代表08寄存器,bit1代表09寄存器。

0x90x8
10

功能码0x5: 写单个线圈寄存器0x05:

功能码0x5的作用是对单个线圈寄存器写值ON/OFF。

发送报文

发送报文由下面几个部分组成,总共12字节:

MBAP header(7字节) + 功能码(1字节) + 线圈寄存器起始地址的高位(1字节) + 线圈寄存器起始地址的低位(1字节) + 要写的值的高位(1字节) + 要写的值的低位(1字节)

将从站中的一个输出写成ON或OFF,0xFF00代表为ON,0x0000代表为OFF。

下面是一个实际的例子:

0x5-request

MBAP header功能码起始地址高字节起始地址低字节写的值的高位写的值的低位
00 6f 00 00 00 06 01050004ff00

在这个例子中,对从站01的0x4号线圈执行ON操作。

响应报文

可以看到,如果写单个线圈成功,返回报文的值和发送报文的值相同:

0x5-request

功能码0x0F:写多个线圈寄存器

将一个从站中的多个线圈寄存器的写为ON或OFF,数据域中置1的位请求相应输出位ON,置0的位请求响应输出为OFF。

发送报文

发送报文由下面几部分组成:

MBAP 功能码 + 起始地址H 起始地址L + 输出数量H 输出数量L + 字节长度 + 输出值H 输出值L

其总长度为 13 + (修改的线圈寄存器数量/8 + 1)。

下面是一个实际的例子

0xF-request

按照协议进行对应的结果如下:

MBAP header功能码线圈寄存器起始位置线圈寄存器的数量字节数第一个byte的值第二个byte的值
01 71 00 00 00 09 010f00 0000 0a027000

其中第一个byte的值是0x70, 转换为二进制是01110000,其中低位bit0代表00寄存器,bit7代表07寄存器。

0x70x60x50x40x30x20x10x0
01110000

第二个byte的值是0x0, 转换为二进制是00000000,其中低位bit0代表08寄存器,bit1代表09寄存器。

0x90x8
00

该请求的作用起始就是将04 05 06寄存器的状态改为ON。

返回报文

返回的报文相对比较简单,由下面几个部分组成:

MBAP header + 功能码 + 起始地址H 起始地址L + 输出数量H 输出数量L

下面是一个实际的例子:

0xF-response

按照协议对应各部分的内容如下:

MBAP header功能码线圈寄存器起始位置线圈寄存器的数量
01 71 00 00 00 06 010f00 0000 0a

功能码0x02:读离散量输入寄存器

功能码0x2和0x1是比较类似的。只是操作的离散量输入寄存器是只读的,没有写操作的接口。

每个离散量输入寄存器可以存储一个bit的信息, 功能码0x02就是用于读取slave中离散量输入寄存器的状态,可以是单个线圈寄存器,也可以是多个连续的线圈寄存器

发送报文

发送报文由下面几个部分组成,总共12字节:

MBAP header(7字节) + 功能码(1字节) + 离散量输入寄存器起始地址的高位(1字节) + 离散量输入寄存器起始地址的低位(1字节) + 离散量输入寄存器数量的高位(1字节) + 离散量输入寄存器数量的低位(1字节)

下面是一个用Modbus-Poll和Modbus-Slave测试的实际的例子,其含义是读取线圈寄存器的起始地址是0x0, 读取数量为 0x0a(十进制10)个。

0x2-request

MBAP header功能码起始地址高字节起始地址低字节寄存器数量的高位寄存器数量的低位
01 b9 00 00 00 06 01010000000a

其中:

TransanctionID = 441, Length = 6。

功能码为0x1,代表读取线圈寄存器。

读取的线圈寄存器的起始地址为0。

读取的线圈寄存器的数量为0xa(十进制10)个。

响应报文

响应报文的长度不是固定的,长度和用户请求的数据长度有关,由下面几个部分组成:

MBAP header(7字节) + 功能码(1字节) + 离散量输入寄存器的值

下面是一个实际的响应报文的内容:

0x2-request

MBAP header功能码字节数请求的数据1请求的数据2
01 b9 00 00 00 05 0101021202

返回的第一个字节12,转化为二进制为00010010, 其中bit0代表00寄存器,bit7代表07寄存器。

0x70x60x50x40x30x20x10x0
00010010

返回的第二个字节02,转化为二进制为00000010, 其中bit0代表08寄存器,bit1代表09寄存器。

0x90x8
10

功能码0x03:读保持寄存器

功能码0x03用于读取保持寄存器的值,从远程设备中读保持寄存器连续块的内容。

发送报文

请求报文的结构如下:

MBAP header + 功能码 + 起始地址H 起始地址L + 寄存器数量H 寄存器数量L(共12字节)

下面是一个实际的例子:

0x3-request

按照协议对照如下:

MBAP header功能码起始地址寄存器数量
05 f1 00 00 00 06 010300 0000 0a

响应报文

响应报文的结构由下面几个部分组成:

MBAP header + 功能码 + 数据长度 + 寄存器数据

数据总长度 = 9 + 寄存器数量 × 2

下面是一个response的结构:

0x3-response

从中我们可以提取出下面的对应关系:

MBAP header功能码字节数第0byte值第1byte值第2byte值第3byte值第4byte值第5byte值第6byte值第7byte值第8byte值第9byte值
05 f1 00 00 00 17 01031401 2c00 0000 0000 3700 0000 0000 6400 0000 3c00 00

由上面的对应关系,我们可以提取出我们想要读取的保持寄存器的值:

第0个寄存器第1个寄存器第2个寄存器第3个寄存器第4个寄存器第5个寄存器第6个寄存器第7个寄存器第8个寄存器第9个寄存器
3000055001000600

功能码0x04:读输入寄存器

功能码0x4用于读取输入寄存器的值,输入寄存器是只读的,因此没有功能码可以写输入寄存器。

发送报文

请求报文格式如下:

MBAP header + 功能码 + 起始地址H 起始地址L + 寄存器数量H 寄存器数量L(共12字节)

下面是一个实际的例子:

0x4-request

MBAP header功能码起始地址寄存器数量
0b f8 00 00 00 06 010400 0000 0a

该请求的含义是读取0-9号寄存器的值。

响应报文

响应报文的结构由下面几个部分组成:

MBAP header + 功能码 + 数据长度 + 寄存器数据

数据总长度 = 9 + 寄存器数量 × 2

下面是一个response的结构:

0x4-response

从中我们可以提取出下面的对应关系:

MBAP header功能码字节数第0byte值第1byte值第2byte值第3byte值第4byte值第5byte值第6byte值第7byte值第8byte值第9byte值
0b f8 00 00 00 17 01041400 0000 0000 c800 0001 2c00 0000 0000 0000 4200 00

由上面的对应关系,我们可以提取出我们想要读取的保持寄存器的值:

第0个寄存器第1个寄存器第2个寄存器第3个寄存器第4个寄存器第5个寄存器第6个寄存器第7个寄存器第8个寄存器第9个寄存器
002000300000660

功能码0x06:写单个保持寄存器

在一个远程设备中写一个保持寄存器。

发送报文

请求报文格式如下:

MBAP header + 功能码 + 寄存器地址H 寄存器地址L + 寄存器值H 寄存器值L(共12字节)

下面是一个实际的例子:

0x6-request

MBAP header功能码保持寄存器地址保持寄存器的值
1F 97 00 00 00 06 010600 0400 64

该请求的含义是向地址为0x4的寄存器写入100。

响应报文

响应报文如下:

MBAP header + 功能码 + 寄存器地址H 寄存器地址L + 寄存器值H 寄存器值L(共12字节)

成功响应的报文与发送报文格式相同。

0x6-response

功能码0x10:写多个保持寄存器

在一个远程设备中写连续寄存器块(1~123个寄存器)

发送报文

请求报文格式如下:

MBAP header + 功能码 + 起始地址H 起始地址L + 寄存器数量H 寄存器数量L + 字节长度 + 寄存器值(13+寄存器数量×2)

0x10-request

MBAP header功能码起始地址长度字节数字节0数据字节1数据字节2数据字节3数据字节4数据字节5数据字节6数据字节7数据字节8数据字节9数据
00 26 00 00 00 1b 011000 0000 0a14 0000 0000 0000 0000 0000 c800 0000 0000 6400 0000 64

响应报文

响应报文如下:

MBAP header + 功能码 + 起始地址H 起始地址L + 寄存器数量H 寄存器数量L(共12字节)

0x10-response

MBAP header功能码起始地址长度
00 26 00 00 00 1b 011000 0000 0a

实用调试工具

在研究modbus的过程中, 大量的使用了modbus poll和 modbus slave软件,这个软件可以很好的帮助理解modbus-tcp协议。

modbus poll: modbus客户端工具(主站)

modbus slave: modbus服务端工具(从站)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1192830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring】Spring IOC DI

Spring IOC & DI IOC DI入门什么是Spring什么是容器什么是IOC IOC介绍传统程序开发解决方案 DI IOC详解Bean的存储Controller(控制器存储)Service(服务存储)Repository(仓库存储)Component(组件存储)Configuration(配置存储) 为什么需要这么多类注解类注解之间的关系方法注…

二十二、W5100S/W5500+RP2040树莓派Pico<SMTP发送邮件>

文章目录 1 前言2 简介2 .1 什么是SMTP?2.2 SMTP是如何工作的?2.3 SMTP、IMAP和POP32.4 SMTP应用场景 3 WIZnet以太网芯片4 SMTP发送邮件示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前…

VINS-Mono-后端优化 (三:视觉雅可比推导)

用逆深度是因为这样可以在优化中从优化3个变量降低到1个,降低优化的维度加快求解速度 用逆深度是因为当距离很远的时候, 1 x \frac{1}{x} x1​ x x x 就会无穷大,而3D点很近的情况也一般不会有,这也是为了数值稳定性 用逆深度的…

微服务治理

微服务治理 什么是服务治理 服务治理 是一种方法和实践,用于管理和监控分布式系统中的服务。它旨在确保服务能够在整个生命周期内可靠地运行、可维护、可扩展和符合业务需求。服务治理涉及一系列的实践、策略和工具,用于管理和优化服务的交付和运行。 …

强化学习 - DQN及进化过程(Double DQN,Dueling DQN)

1.DQN 1.1概念 DQN相对于Q-Learning进行了三处改进: 1.引入神经网络:如下图所示希望能从状态A中提取Q(s,a) 2.经验回放机制:连续动作空间采样时,前后数据具有强关联性,而神经网络训练时要求数据之间具有独立同分布特性…

GZ038 物联网应用开发赛题第4套

2023年全国职业院校技能大赛 高职组 物联网应用开发 任 务 书 (第4套卷) 工位号:______________ 第一部分 竞赛须知 一、竞赛要求 1、正确使用工具,操作安全规范; 2、竞赛过程中如有异议,可向现场考评…

双休日做什么副业?适合不同人群的副业赚钱方法

双休日是大多数人可以用来兼职或者做副业的时间,它是大家可以利用的宝贵时光。通过合理规划和努力工作,双休日的副业可以带来额外的收入,并且可以适应不同人群的需求和兴趣。那么,具体来说,适合不同人群的副业赚钱方法…

什么是特权会话管理

特权会话是由具有管理权限的用户在访问 IT 基础架构中的系统、设备或应用程序(本地或远程)时启动的 Internet 会话,包括在该会话期间执行的所有活动。 特权会话可以是数据库或安全管理员,通过 RDP 或 SSH 会话访问数据中心的机密…

Docker 安装与优化

一、安装Docker 1、关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02、安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2#解释 yum-utils #提供了yum-config-manager工具 device mapper #是linux内核中支持逻辑卷…

高压MOS/低压MOS在单相离线式不间断电源上的应用-REASUNOS瑞森半导体

一、前言 单相离线式不间断电源只是备援性质的UPS,市电直接供电给用电设备再为电池充电,一旦市电供电品质不稳或停电时,市电的回路会自动切断,电池的直流电会被转换成交流电接手供电的任务,直到市电恢复正常。UPS只有…

Zeitgeist ZTG Token以及其预测市场加入Moonbeam生态

波卡上的首选多链开发平台Moonbeam宣布与Zeitgeist达成XCM集成,将ZTG Token引入Moonbeam。此集成将使波卡内的Moonbeam和Zeitgeist网络之间的流动性得以流动,并通过Moonbeam的互连合约实现远程链集成。 Zeitgeist是一个基于波卡的Substrate区块链框架构…

Flink SQL自定义标量函数(Scalar Function)

使用场景: 标量函数即 UDF,⽤于进⼀条数据出⼀条数据的场景。 开发流程: 实现 org.apache.flink.table.functions.ScalarFunction 接⼝实现⼀个或者多个⾃定义的 eval 函数,名称必须叫做 eval,eval ⽅法签名必须是 p…

前端训练营:1v1私教,帮你拿到满意的offer

Hello,大家好,我是 Sunday。 熟悉我的小伙伴都知道,我最近这几年一直在做前端教育相关的工作。因为这类工作的原因,让我深刻的感受到这几年整个互联网行业的变化。 大量的公司裁员,导致找工作的人急速增加&#xff0…

解压游戏资源,导出游戏模型

游戏中有很多好看的角色,地图等等资源。 你有没有想过,把他们导出到自己的游戏中进行魔改又或则玩换肤等操作呢? 相信很多同学都喜欢拳皇中的角色, 那么我们今天就拿拳皇15举例子,导出他的资源。 首先要先安装好这个…

算法:穷举,暴搜,深搜,回溯,剪枝

文章目录 算法基本思路例题全排列子集全排列II电话号码和字母组合括号生成组合目标和组合总和优美的排列N皇后有效的数独解数独单词搜索黄金矿工不同路径III 总结 算法基本思路 穷举–枚举 画出决策树设计代码 在设计代码的过程中,重点要关心到全局变量&#xff…

软文推广优化技巧:如何写出有创意的文案

今天媒介盒子要给大家分享的干货内容就是:如何写出有创意的文案。 时代背景会改变,大众的趣味焦点也会转移,同样再好的文案也会失效,但文案背后的触发机制不会变。下面是能够使广告文案起作用的关键因素: 一、 研究产…

偶数科技亮相2023中国程序员节——数据库技术高峰论坛

2023年10月24日,由中国软件行业协会主办的“中国程序员节”在北京、深圳、宁波多地同时召开,其中数据库技术高峰论坛在北京举办,偶数科技亮相本次论坛并分享了题为《大模型、实时需求推动湖仓平台走向开放》的主题演讲。 国际局势复杂、科技竞…

面包机上架亚马逊美国站UL1026测试报告办理

面包机(又称烤面包机)是一种家用电器,用于制作面包、烤饼等食品。在亚马逊美国站销售面包机时,可能需要提供 UL 报告以确保产品安全性。UL1026 是适用于面包机的美国安全标准。 面包机UL1026报告是按照美国国家电气规范NFPA 70所规…

Django生鲜蔬菜采购系统-计算机毕设 附源码 24033

Django生鲜蔬菜采购系统 目 录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2 生鲜蔬菜采购系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流…

Bean_AOP

Bean 源码 https://github.com/cmdch2017/Bean_IOC.git 获取Bean对象 BeanFactory Bean的作用域 第三方Bean需要用Bean注解 比如消息队列项目中,需要用到Json的消息转换器,这是第三方的Bean对象,所以不能用Component,而要用B…