当前位置: 首页 > article >正文

Modbus协议(TCP)

        从今开始,会详细且陆续整理各类的通信协议,以便在需要且自身忘记的情况下,迅速复习。如有错误之处,还请批评指正。

一、Modbus协议的简述

        Modbus协议作为应用层协议,基于主从设备模型,主设备负责请求消息,从设备进行消息的应答。

传输支持

  • 物理层:支持RS-232、RS-485等串行链路及以太网(TCP/IP) 
  • 协议版本:包括Modbus RTU(二进制高效传输)、Modbus ASCII(可读性高)、Modbus TCP(基于以太网)

本文重点叙述TCP的方式。

二、工作机制

  • 请求-响应模式:主设备发送包含 功能码 和 数据地址 的请求帧,从设备返回操作结果或数据。例如:
    • 功能码03H:读取保持寄存器(如读取温度设定值) 
    • 功能码06H:写入单个保持寄存器(如调整电机转速) 
  • 数据帧结构
    • Modbus RTU帧:地址 + 功能码 + 数据 + CRC校验 
    • Modbus TCP帧:MBAP头(事务ID协议ID后续报文的字节数设备地址) + PDU(功能码 + 数据),注:事务ID,当需要进行并发请求的时候,就可使用不同的事务ID,避免匹配错误。 单元ID:多PLC通信的场景下,需要使用单元ID,以保证每条信息是专属的。

三、功能码

寄存器类型功能码操作类型数据单位典型应用
线圈寄存器01H位(Bit)监控继电器、电磁阀状态
05H单个位控制单个执行机构
0FH多个位批量控制执行机构
离散输入寄存器02H位(Bit)监测外部传感器信号
输入寄存器04H字(Word)获取传感器实时数据
保持寄存器03H字(Word)读取设备配置参数
06H单个字修改单个设备参数
10H多个字批量配置设备参数

四、寄存器类型

        这里简要叙述下寄存器的类型,不同的寄存器它所占的空间大小和读写权限都是不同的

寄存器类型功能码范围读写权限典型应用
线圈寄存器01H、05H、0FH读写控制开关量输出(如继电器) 
离散输入寄存器02H只读监测开关量输入(如急停信号) 
输入寄存器04H只读读取模拟量输入(如传感器电压) 
保持寄存器03H、06H、10H读写存储设备参数或实时数据(如PID参数)

五、异常码

在Modbus协议中,当从站设备(服务器)检测到请求错误时,会返回包含 异常功能码(Error Function Code)异常码(Error Code) 的响应报文。

  1. 异常功能码:原功能码的最高位被置为1(即功能码 + 0x80)。例如:
    • 原功能码 0x03(读保持寄存器)→ 异常功能码 0x83
    • 原功能码 0x10(写多个寄存器)→ 异常功能码 0x90
  2. 异常码:紧随异常功能码后,占1字节,表示具体错误类型(如非法地址、非法功能等)
  3. 以下列举出常用的异常码
异常码(十六进制)名称含义典型场景
0x01非法功能 (Illegal Function)请求的功能码不被支持或未实现。例如:向只读寄存器发送写操作。主站发送功能码 0x05(写线圈),但设备不支持该功能。 
0x02非法数据地址 (Illegal Data Address)寄存器地址超出设备允许范围。请求读取地址 40010,但设备仅支持 40001-40005。 
0x03非法数据值 (Illegal Data Value)写入的数据值不合法(如超出寄存器范围)。试图向16位寄存器写入 0x10000(最大值应为 0xFFFF)。 
0x04设备故障 (Slave Device Failure)从站设备内部错误(如硬件故障)。从站设备因电源波动导致处理失败。 
0x05确认 (Acknowledge)从站已接收请求但需要更长时间处理(需主站轮询完成状态)。主站请求写入大量数据,从站返回 0x05 表示正在处理。 
0x0B目标设备未响应 (Target Device Failed to Respond)网关无法将请求转发到目标设备。网络中断或目标设备离线。

六、举例

        最后,我们来看三段报文

报文1:00 01 00 00 00 06 01 06 00 00 00 01
  • MBAP头
    • Transaction ID: 00 01(事务ID为1)
    • Protocol ID: 00 00(Modbus协议)
    • Length: 00 06(后续报文长度为6字节)
    • Unit ID: 01(设备地址1)
  • PDU
    • 功能码: 06(写单个保持寄存器)
    • 寄存器地址: 00 00(地址0x0000)
    • 写入值: 00 01(值为1)
  • 作用:向地址 0x0000 的保持寄存器写入值 1
报文2:00 01 00 00 00 05 01 03 00 00 00 0A
  • MBAP头
    • Transaction ID: 00 01(事务ID为1)
    • Protocol ID: 00 00(Modbus协议)
    • Length: 00 05(后续报文长度为5字节)
    • Unit ID: 01(设备地址1)
  • PDU
    • 功能码: 03(读保持寄存器)
    • 寄存器起始地址: 00 00(地址0x0000)
    • 读取数量: 00 0A(读取10个寄存器)
  • 作用:从地址 0x0000 开始读取10个保持寄存器的值

报文3:00 01 00 00 00 17 01 03 14 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A

  • MBAP头
    • Transaction ID: 00 01(事务ID为1)
    • Protocol ID: 00 00(Modbus协议)
    • Length: 00 17(后续报文长度为23字节)
    • Unit ID: 01(设备地址1)
  • PDU
    • 功能码: 03(读保持寄存器)
    • 字节数: 14(数据总字节20)
    • 寄存器数据: 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A(10个寄存器的值)

下面来一段错误报文的机制:
        场景:主站尝试读取保持寄存器地址 400101(十进制地址100),但从站设备仅支持寄存器地址 400001-400050,导致地址越界错误

        请求报文:00 01 00 00 00 06 01 03 00 64 00 01

字段值(十六进制)说明
事务ID00 01事务标识符(自增值,用于匹配请求与响应)。
协议ID00 00Modbus TCP协议固定标识符(0x0000)。
长度00 06后续数据长度6字节(单元ID + PDU)。
单元ID01从站地址(本例为1)。
功能码03读保持寄存器操作。
起始地址00 64十进制地址100(对应Modbus地址400101)。
寄存器数量00 01读取1个寄存器。

        响应报文:00 01 00 00 00 03 01 83 02

字段值(十六进制)说明
事务ID00 01与请求报文的事务ID一致,用于匹配请求与响应。
协议ID00 00固定标识符(0x0000)。
长度00 03后续数据长度3字节(单元ID + 异常功能码 + 异常码)。
单元ID01从站地址(与请求一致)。
异常功能码83原功能码 03 + 0x80(表示异常响应)。
异常码02错误类型为 非法数据地址(从站不支持地址400101)。

http://www.kler.cn/a/574389.html

相关文章:

  • 前端基础之ajax
  • 人工智能直通车系列06【Python 基础与数学基础】(属性与方法概率论:概率基本概念)
  • 深入解析 Java 进程的内存占用-ByAI
  • MariaDB Galera 原理及用例说明
  • 键值对(C++实现)
  • vue2.6附件预览及下载
  • 大模型——基于 DIFY 的自动化数据分析实战
  • 爬虫逆向:脱壳工具 frida-dexdump 的使用详解
  • 安全见闻之网络安全新兴术语
  • 深度学习Save Best、Early Stop
  • 全面复习回顾——C++语法篇2
  • 华为OD机试-九宫格游戏(Java 2024 E卷 100分)
  • fetch为什么加了允许跨域请求mode: ‘no-cors‘,添加的多个header就丢失了?
  • java8 list分组
  • JavaWeb-idea配置smart tomcat
  • 大数据环境(单机版) Flume传输数据到Kafka
  • 算法之 前缀和
  • vector详解
  • netty中Future和ChannelHandler
  • 鸿蒙Next网络请求~上传文件pdf