Modbus协议简介与常用测试指令说明
| Date | Author | Version | Note |
|---|---|---|---|
| 2022.07.19 | Dog Tao | V1.0 | 1. 完成了文档的撰写。 |
| 2023.08.04 | Dog Tao | V1.2 | 1. 修订文档,增加了Modbus协议简介小节。 |
本文档提供ModbusPoll调试软件与官方部署文档合辑资源(CSDN平台)。
文章目录
- Modbus协议简介
- 发展历史
- 主要技术说明
- 基本规范与功能码
- Modbus寄存器地址规则
- Modbus RTU报文基本格式
- 功能码01:读线圈寄存器(开关量输出)
- 功能码02:读离散寄存器(开关量输入)
- 功能码03:读保持寄存器(模拟量输出)
- 功能码04:读输入寄存器(模拟量输入)
- 功能码05:写单线圈(开关量输出)
- 功能码06:写单保持寄存器(模拟量输出)
- 功能码15:写多线圈(开关量输出)
- 功能码16:写多保持寄存器(模拟量输出)
- 读寄存器测试指令
- 线圈寄存器-读命令(0x01)
- 离散寄存器-读命令(0x02)
- 保持寄存器-读命令(0x03)
- 输入寄存器-读命令(0x04)
Modbus协议简介
发展历史
Modbus是一种通信协议,广泛用于工业控制系统之间的通信。它由Modicon(现在的施耐德电气)于1979年开发,用于与其PLC(可编程逻辑控制器)进行通信。Modbus协议主要有两个版本:Modbus RTU和Modbus TCP/IP。
-
Modbus RTU:Modbus RTU是一种串行通信协议,通常在RS-485串行接口上运行。它是二进制协议,数据在总线上以连续字节的形式传输。每条消息都以设备地址开始,由功能代码(指示操作类型)和数据字节(包含操作数据)组成,并以两字节的循环冗余校验(CRC)结束,用于检测消息传输中的错误。
-
Modbus TCP/IP:Modbus TCP/IP是基于以太网的Modbus协议版本。它在Modbus RTU的基础上增加了MBAP(Modbus Application Protocol)头部,以在TCP/IP网络上提供设备寻址和错误检测。Modbus TCP/IP通常在502端口上运行。
主要技术说明
-
寻址:在Modbus协议中,每个设备都有一个唯一的地址。在RS-485网络中,地址范围是0-247。地址0是广播地址,发送到此地址的消息将被网络上的所有设备接收。
-
寄存器:Modbus设备包含四种类型的寄存器:离散输入(只读)、线圈(可读写)、输入寄存器(只读)和保持寄存器(可读写)。每个寄存器都有一个唯一的地址,用于从设备读取或向设备写入数据。
-
功能代码:Modbus协议定义了一组功能代码,用于指示要执行的操作,如读取寄存器(功能代码03或04)或写入寄存器(功能代码06或16)。如果设备不能执行请求的操作,它将返回一个异常响应,包含一个错误码。
-
消息格式:Modbus消息由地址、功能码、数据和错误检查部分组成。在Modbus RTU中,错误检查通过CRC实现,而在Modbus TCP/IP中,通过MBAP头部的协议标识符和长度字段实现。
Modbus协议是一种简单、开放的协议,广泛用于工业自动化和嵌入式系统应用。尽管它已经存在了几十年,但由于其稳定性和易用性,它仍然是工业通信的主要标准之一。
基本规范与功能码
Modbus寄存器地址规则
Modbus协议定义的寄存器地址是5位十进制地址,即:
- 线圈寄存器(Coils Register)地址:00001~09999
- 离散寄存器(Discrete Register)地址:10001~19999
- 输入寄存器(Input Register)地址:30001~39999
- 保持寄存器(Holding Register)地址:40001~49999
由于上述各类地址是唯一对应的,因此有些资料就以其第一个数字区分各类地址,即:0x代表线圈寄存器(CR)类地址,1x代表离散寄存器(DR)类地址、 3x代表输入寄存器(IR)类地址、4x代表保持寄存器(HR)类地址。
在实际编程中,由于前缀的区分作用,所以只需说明后4位数,而且需转换为4位十六进制地址。
Modbus RTU报文基本格式
| 间隔 | 目标站号 | 功能码 | 数据 | CRC16校验 |
|---|---|---|---|---|
| 起始应有不小于3.5个字符的报文间隔 | 1字节 | 1字节 | n字节 | 2字节 |
下面对于各请求命令的“应答格式”的描述是指命令被正确执行时的应答格式。若CPU接收到错误的命令或者命令被执行错误,则返回的应答帧中“功能码”部分变为如下数据:功能码的最高位置1后得到的数据。比如功能码为01,若响应错误,则返回的功能码为0x81。
功能码01:读线圈寄存器(开关量输出)
- 请求格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址 低字节 | 读取个数 高字节 | 读取个数 低字节 | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 01 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
- 正确应答格式:
| 站号 | 功能码 | 返回数据字节数 | 返回数据字节1 | 返回数据字节2 | … | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 01 | 1字节 | 1字节 | 1字节 | … | 2字节 |
功能码02:读离散寄存器(开关量输入)
- 请求格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址 低字节 | 读取个数 高字节 | 读取个数 低字节 | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 02 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
- 正确应答格式:
| 站号 | 功能码 | 返回数据字节数 | 返回数据字节1 | 返回数据字节2 | … | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 02 | 1字节 | 1字节 | 1字节 | … | 2字节 |
功能码03:读保持寄存器(模拟量输出)
- 请求格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址 低字节 | 读取个数 高字节 | 读取个数 低字节 | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 03 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
- 正确应答格式:
| 站号 | 功能码 | 返回数据字节数 | 寄存器1高字节 | 寄存器1低字节 | … | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 03 | 1字节 | 1字节 | 1字节 | … | 2字节 |
功能码04:读输入寄存器(模拟量输入)
- 请求格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址 低字节 | 读取个数 高字节 | 读取个数 低字节 | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 04 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
- 正确应答格式:
| 站号 | 功能码 | 返回数据字节数 | 寄存器1高字节 | 寄存器1低字节 | … | CRC |
|---|---|---|---|---|---|---|
| 1字节 | 04 | 1字节 | 1字节 | 1字节 | … | 2字节 |
功能码05:写单线圈(开关量输出)
- 请求格式:
| 目标站号 | 功能码 | 线圈地址 高字节 | 线圈地址 低字节 | 强制值 高字节 | 强制值 低字节 | CRC校验码 |
|---|---|---|---|---|---|---|
| 1字节 | 05 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
注:强制值= 0xFF00,则置线圈为ON;强制值=0x0000,则置线圈为OFF。
- 应答格式:若设置成功,原文返回
功能码06:写单保持寄存器(模拟量输出)
- 请求格式:
| 目标站号 | 功能码 | 寄存器地址 高字节 | 寄存器地址 低字节 | 强制值 高字节 | 强制值 低字节 | CRC校验码 |
|---|---|---|---|---|---|---|
| 1字节 | 06 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
- 应答格式:若设置成功,原文返回
功能码15:写多线圈(开关量输出)
- 请求格式:
| 目标 站号 | 功能码 | 起始地址 高字节 | 起始地址低字节 | 数量 高字节 | 数量 低字节 | 强制值字节数 | 强制值 第1字节 | … | CRC |
|---|---|---|---|---|---|---|---|---|---|
| 1字节 | 15 | 1字节 | 1字节 | 1字节 | 1字节 | 1字节 | 1字节 | … | 2字节 |
- 正确应答格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址低字节 | 数量 高字节 | 数量 低字节 | CRC校验码 |
|---|---|---|---|---|---|---|
| 1字节 | 15 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
功能码16:写多保持寄存器(模拟量输出)
- 请求格式:
| 目标 站号 | 功能码 | 起始地址 高字节 | 起始地址低字节 | 数量 高字节 | 数量 低字节 | 强制值字节数 | 强制值1 高字节 | 强制值1 低字节 | … | CRC |
|---|---|---|---|---|---|---|---|---|---|---|
| 1字节 | 16 | 1字节 | 1字节 | 1字节 | 1字节 | 1字节 | 1字节 | 1字节 | … | 2字节 |
- 正确应答格式:
| 目标站号 | 功能码 | 起始地址 高字节 | 起始地址低字节 | 数量 高字节 | 数量 低字节 | CRC 校验码 |
|---|---|---|---|---|---|---|
| 1字节 | 16 | 1字节 | 1字节 | 1字节 | 1字节 | 2字节 |
读寄存器测试指令
线圈寄存器-读命令(0x01)
| 从机地址 | 寄存器地址 | 寄存器数量 | 网络指令 | modbus指令 | 说明 | 参考回复 |
|---|---|---|---|---|---|---|
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 01 03 E7 00 01 4D B9 | 读取输入寄存器第一个位值 | 01 01 01 00 51 88 |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 01 03 E7 00 02 0D B8 | 读取输入寄存器前二个位值 | |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 01 03 E7 00 04 8D BA | 读取输入寄存器前四个位值 | |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 01 03 E7 00 08 8D BF | 读取输入寄存器前八个位值 |
离散寄存器-读命令(0x02)
| 从机地址 | 寄存器地址 | 寄存器数量 | 网络指令 | modbus指令 | 说明 |
|---|---|---|---|---|---|
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 02 03 E7 00 01 09 B9 | 读取输入寄存器第一个位值 |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 02 03 E7 00 02 49 B8 | 读取输入寄存器前二个位值 |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 02 03 E7 00 04 C9 BA | 读取输入寄存器前四个位值 |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 02 03 E7 00 08 C9 BF | 读取输入寄存器前八个位值 |
保持寄存器-读命令(0x03)
| 从机地址 | 寄存器地址 | 寄存器数量 | 网络指令 | modbus指令 | 说明 |
|---|---|---|---|---|---|
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 03 03 E7 00 02 74 78 | 读取输入寄存器第一个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 03 03 E7 00 04 F4 7A | 读取输入寄存器前二个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 03 03 E7 00 08 F4 7F | 读取输入寄存器前四个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 03 03 E7 00 10 F4 75 | 读取输入寄存器前八个32位数值(浮点数) |
输入寄存器-读命令(0x04)
| 从机地址 | 寄存器地址 | 寄存器数量 | 网络指令 | modbus指令 | 说明 |
|---|---|---|---|---|---|
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 04 03 E7 00 02 C1 B8 | 读取输入寄存器第一个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 04 03 E7 00 04 41 BA | 读取输入寄存器前二个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 04 03 E7 00 08 41 BF | 读取输入寄存器前四个32位数值(浮点数) |
| 0x01 | 0x999 | 0x02 | 00 32 17 | 01 04 03 E7 00 10 41 B5 | 读取输入寄存器前八个32位数值(浮点数) |
相关文章:
Modbus协议简介与常用测试指令说明
DateAuthorVersionNote2022.07.19Dog TaoV1.01. 完成了文档的撰写。2023.08.04Dog TaoV1.21. 修订文档,增加了Modbus协议简介小节。 本文档提供ModbusPoll调试软件与官方部署文档合辑资源(CSDN平台)。 文章目录 Modbus协议简介发展历史主要技…...
EXCEL里数值列如何显示序号?如何重新排序? 怎么取得排序后的序号?
目录 1 EXCEL里如何显示序号? 2 如何重新排序? 3 怎么取得排序后的序号? 3.1 rank() 的序号可能不连续 3.2 方法2:SUMPRODUCT((C7>C$7:C$12)/COUNTIF(C$7:C$12,C$7:C$12))1 EXCEL里如何显示序号?如何重新排序…...
kubernetes 集群利用 efk 收集容器日志
文章目录 [toc]前情提要制作 centos 基础镜像准备 efk 二进制文件部署 efk 组件配置 namespace配置 gfs 的 endpoints配置 pv 和 pvc部署 elasticsearchefk-cmefk-svcefk-sts 部署 filebeatfilebeat-cmfilebeat-ds 部署 kibanakibana-cmkibana-svckibana-dp使用 nodeport 访问 …...
安防视频监控汇聚平台EasyCVR在移动端火狐浏览器中云台显示的优化
安防监控视频EasyCVR视频融合平台基于云边端一体化架构,具有强大的数据接入、视频监控汇聚、处理及分发能力,平台能对前端接入设备进行统一集中管理,支持采用设备树对设备进行分组、分级管理,支持设备状态监测、云端运维等功能&am…...
selenium官文文档阅读总结(day 3)
1.关联型xpath的用法 driver.find_element(By.XPATH,//a[text()"xxx"]/ancestor::祖先元素的标签名//……) 2.selenium等待 等待的作用 :在系统运行的过程中,等待网页内容的加载显示。需要耗费的时间,与网络速度、接口的复杂程度…...
【pandas百炼成钢】数据预览与预处理
知识目录 前言一、数据查看1 - 查看数据维度2 - 随机查看5条数据3 - 查看数据前后5行4 - 查看数据基本信息5 - 查看数据统计信息|数值6 - 查看数据统计信息|非数值7 - 查看数据统计信息|整体 二、缺失值处理8 - 计算缺失值|总计9 …...
怎么查到企业的供应商和客户?
企业的供应商和客户是什么? 其实不需要过多介绍,我们对供应商和客户都有自己的理解,供应商就是负责企业产品的供应,企业从供应商那里买材料进行加工得到的产品,卖给客户。 官方来说供应商是向企业和竞争对手提供各种…...
智能物流千人俱乐部---行业必备神器
千人俱乐部前两天正式推出了。 智能物流千人俱乐部详情 很多行业内的甲方和乙方的朋友过来问,这个千人俱乐部到底怎么玩?今天再来解释一下。 1、为什么搞这个千人俱乐部? 一个原因是:研习社天天都有甲方粉丝让推荐设备厂家&#x…...
uniapp uview文件上传的文件不是文件流,该如何处理?用了uni.chooseImage预览功能要如何做
在使用uniapp开发,运用的ui是用uview,这边需要做一个身份认证,如下图 使用的是uview的u-upload组件,可是这个组件传给后端的不是文件流 后端接口需要的是文件流格式,后面使用了uniapp的选择图片或者拍照的api&#x…...
pktgen-dpdk arm编译问题 “Platform must be built with RTE_FORCE_INTRINSICS“
编译报错 /usr/include/rte_atomic_32.h:9:4: error: #error Platform must be built with RTE_FORCE_INTRINSICS解决办法: 我是在 arm架构服务器上编译出现这个,要定义 RTE_FORCE_INTRINSICS 在meson.build中 增加gcc编译参数 add_project_arguments(…...
用html+javascript打造公文一键排版系统12:删除附件说明中“附件:”里的空格
如果我们在输入附件说明时在“附件:”之间加入空格,那么排版时就要删除这些空格。 因为string对象replace()支持正则表达式,于是考虑用replace()来完成。 写了一段只有一个多余空格的代码来测试: <!DOCTYPE HTML> <HT…...
容器技术:Docker搭建(通俗易懂)
目录 Docker搭建环境准备Docker安装1、查看服务器是否安装Docker2、卸载Docker3、安装Dokcer依赖环境4、配置Docker国内阿里云镜像5、安装Docker6、查看Docker信息7、配置阿里云镜像加速8、镜像安装10、运行实例11、查看实例状态12、测试 Docker命令集合 Docker搭建 环境准备 …...
Day 16 C++ 友元(friend)
目录 什么是友元(friend) 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 什么是友元(friend) 友元是一种访问控制的机制,它允许一个类或函数访问另一个类的私有成员。通过友元关系,可以在需要…...
步进电机1
引脚说明: VCC:电源输入口 DC:9-42VDC:电源的取值范围 AB组:用于连接电机的四条线 STEP&PUL:脉冲信号接口,用于控制速度。无细分的情况下一个脉冲步进电机走一步。 DIR:方向信号接口&#x…...
PHP-简单项目引起的大麻烦--【白嫖项目】
强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 首页小插曲小插曲完了么?必要的项目知识PHPThinkPHPThinkPHP的MVCThinkTemplateThinkPHP 6和ThinkPHP 5 phpStudy 设置导数据库展示页面数据库表结构项目目录如图…...
Excel如何把两列互换
第一步:选择一列 打开excel,选中一列后将鼠标放在列后,让箭头变成十字方向。 第二步:选择Shift键 按住键盘上的Shift键,将列往后移动变成图示样。 第三步:选择互换 完成上述操作后,松开鼠标两…...
Java基础面试题2
Java基础面试题 一、IO和多线程专题 1.介绍下进程和线程的关系 进程:一个独立的正在执行的程序 线程:一个进程的最基本的执行单位,执行路径 多进程:在操作系统中,同时运行多个程序 多进程的好处:可以充…...
Typescript 第八章 异步编程,并行和并发(JavaScript事件循环,异步流,多线程类型安全)
Typescript第八章 异步编程,并发和并行 异步API,比如说回调,promise和流。 JavaScript引擎在一个线路中多路复用任务,而其他任务则处于空闲状态。这种事件循环是JavaScript引擎的标准线程模型。 多路复用是指在一个线程中同时处…...
c++ 打印当前时间(精确到毫秒)
打印时间精确到毫秒好实现,但是那种对用户可读性不好,更适合开头记一次结尾记一次,打印中间减出来的程序运行时间。 但是因为一些情况,我开多线程开的不方便打印结束时间,同事跟我说那你把开始时间打印一下࿰…...
mapstruct 错误 java.lang.NoSuchMethodError: Ljava/lang/Double 错误
问题描述 在使用 mapstruct 的过程中遇到错误 java.lang.NoSuchMethodError: Ljava/lang/Double 错误 问题解决 maven clean, 然后 maven install Build -> Rebuild Project 执行 maven install 时, 如果报错 找不到 xxx 类, 但 ctrl鼠标左键 发现可以点进去这个类, 那…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
