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

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

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

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

你可能感兴趣的:(通信协议,tcp/ip,网络,网络协议)