三、帧结构与报文格式3.1 Modbus RTU 帧结构3.1.1 帧组成字段长度说明起始≥3.5字符静默帧分隔符非显式字节地址域1字节0广播1-247从站地址248-255保留功能码1字节1-127公共功能码128-255异常响应数据域N字节随功能码变化寄存器地址、数量、写入值等CRC校验2字节CRC-16低字节在前小端序结束≥3.5字符静默帧结束标志3.1.2 完整示例请求读1号从站从地址0x0000开始读2个保持寄存器01 03 00 00 00 02 C4 0B │ │ │ │ └─────┘ │ │ │ │ └── CRC: 0x0BC4低字节0xC4高字节0x0B │ │ │ └── 数量: 2 (0x0002) │ │ └── 起始地址: 0x0000 │ └── 功能码: 03 (读保持寄存器) └── 地址: 1响应假设寄存器0x00000x12340x00010x567801 03 04 12 34 56 78 D7 2E │ │ │ │ └─────┘ │ │ │ │ └── CRC: 0x2ED7低字节0xD7高字节0x2E │ │ │ └── 数据: 0x1234, 0x5678共4字节 │ │ └── 字节数: 4 │ └── 功能码: 03 └── 地址: 13.2 Modbus TCP 帧结构3.2.1 帧组成字段长度说明事务标识符2字节客户端生成服务器原样返回用于匹配请求/响应协议标识符2字节必须为 0x0000Modbus协议非0为其他协议长度2字节后续字节总数 1单元ID PDU长度单元标识符1字节原RTU地址用于串口子设备路由TCP网关场景功能码1字节同RTU数据域N字节同RTU注意Modbus TCP 没有 CRC 字段由 TCP/IP 协议栈提供校验3.2.2 完整示例请求读单元ID1的设备从地址0x0000读2个保持寄存器00 01 00 00 00 06 01 03 00 00 00 02 │ │ │ │ │ │ │ └──────┘ │ │ │ │ │ │ │ └── 数据域与RTU完全相同 │ │ │ │ │ │ └── 单元ID: 1 │ │ │ │ │ └── 长度: 61字节单元ID 5字节PDU │ │ │ │ └── 协议标识符低位: 0 │ │ │ └── 协议标识符高位: 0 → 协议ID 0x0000 │ │ └── 事务标识符低位: 1 │ └── 事务标识符高位: 0 → 事务ID 0x0001 └── 事务标识符(0x0001)长度字段详解0x0006表示后续有6个字节单元ID 1 功能码 1 数据域 4。响应00 01 00 00 00 05 01 03 02 12 34 │ │ │ │ │ │ │ │ │ └── 数据高位 │ │ │ │ │ │ │ │ └── 数据低位 │ │ │ │ │ │ │ └── 字节数: 2 │ │ │ │ │ │ └── 功能码: 03 │ │ │ │ │ └── 单元ID: 1 │ │ │ │ └── 长度: 5 (1121? 重新计算) │ │ │ └── 协议ID: 0 │ │ └── 事务ID: 1长度实际计算0x0005 5后续字节数 单元ID(1) 功能码(1) 字节数(1) 数据(2) 5正确。3.3 RTU 与 TCP 帧格式对比图RTU 帧: ----------------------------------------------------- | 地址 | 功能码 | 数据 | | CRC低 | CRC高 | | (1 B) | (1 B) | (N B) | | (1 B) | (1 B) | ----------------------------------------------------- ↑ 静默时间分隔 TCP 帧封装在TCP段内: ------------------------------------------------------------- | 事务ID | 协议ID | 长度 | 单元ID | 功能码 | 数据 | | | (2 B) | (2 B) | (2 B) | (1 B) | (1 B) | (N B) | | ------------------------------------------------------------- ↑ MBAP 头部7字节 ↑ PDU协议数据单元