完整的技术参考指南
Modbus是一种串行通信协议,最初由Modicon公司(现在的施耐德电气)在1979年发布,用于PLC(可编程逻辑控制器)间的通信。Modbus RTU是Modbus协议的一种实现方式,采用二进制编码,适用于串行通信。
Modbus RTU消息帧由以下部分组成:
| 字段 | 字节长度 | 描述 |
|---|---|---|
| 设备地址 | 1 | 从机地址(0-247) |
| 功能码 | 1 | 指定要执行的操作 |
| 数据区 | 0-252 | 包含发送的数据或请求参数 |
| CRC校验 | 2 | 循环冗余校验码 |
功能码定义了Modbus消息的类型和操作。以下是常用的功能码:
| 功能码 | 名称 | 操作 |
|---|---|---|
| 01 (0x01) | 读线圈状态 | 读取一组开关输出状态(线圈) |
| 02 (0x02) | 读离散输入状态 | 读取一组开关输入状态(触点) |
| 03 (0x03) | 读保持寄存器 | 读取一组模拟输出值(保持寄存器) |
| 04 (0x04) | 读输入寄存器 | 读取一组模拟输入值(输入寄存器) |
| 05 (0x05) | 写单个线圈 | 写入单个线圈状态 |
| 06 (0x06) | 写单个保持寄存器 | 写入单个保持寄存器值 |
| 15 (0x0F) | 写多个线圈 | 写入多个线圈状态 |
| 16 (0x10) | 写多个保持寄存器 | 写入多个保持寄存器值 |
此功能码用于读取从机的一个或多个线圈状态。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x01 |
| 起始地址高字节 | 2 | 线圈起始地址高位 |
| 起始地址低字节 | 3 | 线圈起始地址低位 |
| 线圈数量高字节 | 4 | 要读取的线圈数量高位 |
| 线圈数量低字节 | 5 | 要读取的线圈数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x01 |
| 字节数 | 2 | 后续数据字节数 |
| 线圈状态 | 3-n | 线圈状态数据(每个位代表一个线圈) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
此功能码用于读取从机的一个或多个离散输入状态。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x02 |
| 起始地址高字节 | 2 | 离散输入起始地址高位 |
| 起始地址低字节 | 3 | 离散输入起始地址低位 |
| 输入数量高字节 | 4 | 要读取的输入数量高位 |
| 输入数量低字节 | 5 | 要读取的输入数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x02 |
| 字节数 | 2 | 后续数据字节数 |
| 输入状态 | 3-n | 输入状态数据(每个位代表一个输入) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
此功能码用于读取从机的一个或多个保持寄存器的值。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x03 |
| 起始地址高字节 | 2 | 寄存器起始地址高位 |
| 起始地址低字节 | 3 | 寄存器起始地址低位 |
| 寄存器数量高字节 | 4 | 要读取的寄存器数量高位 |
| 寄存器数量低字节 | 5 | 要读取的寄存器数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x03 |
| 字节数 | 2 | 后续数据字节数 |
| 寄存器值 | 3-n | 寄存器值数据(每个寄存器占2个字节) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
此功能码用于读取从机的一个或多个输入寄存器的值。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x04 |
| 起始地址高字节 | 2 | 输入寄存器起始地址高位 |
| 起始地址低字节 | 3 | 输入寄存器起始地址低位 |
| 寄存器数量高字节 | 4 | 要读取的寄存器数量高位 |
| 寄存器数量低字节 | 5 | 要读取的寄存器数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x04 |
| 字节数 | 2 | 后续数据字节数 |
| 寄存器值 | 3-n | 寄存器值数据(每个寄存器占2个字节) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
此功能码用于写入从机的单个线圈状态。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x05 |
| 输出地址高字节 | 2 | 线圈地址高位 |
| 输出地址低字节 | 3 | 线圈地址低位 |
| 输出值高字节 | 4 | 线圈值高位(0xFF为ON,0x00为OFF) |
| 输出值低字节 | 5 | 线圈值低位(0x00) |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
响应帧与请求帧相同,表示操作成功。
此功能码用于写入从机的单个保持寄存器值。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x06 |
| 寄存器地址高字节 | 2 | 寄存器地址高位 |
| 寄存器地址低字节 | 3 | 寄存器地址低位 |
| 寄存器值高字节 | 4 | 寄存器值高位 |
| 寄存器值低字节 | 5 | 寄存器值低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
响应帧与请求帧相同,表示操作成功。
此功能码用于写入从机的多个线圈状态。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x0F |
| 起始地址高字节 | 2 | 线圈起始地址高位 |
| 起始地址低字节 | 3 | 线圈起始地址低位 |
| 线圈数量高字节 | 4 | 要写的线圈数量高位 |
| 线圈数量低字节 | 5 | 要写的线圈数量低位 |
| 字节数 | 6 | 后续数据字节数 |
| 线圈值 | 7-n | 线圈状态数据(每个位代表一个线圈) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x0F |
| 起始地址高字节 | 2 | 线圈起始地址高位 |
| 起始地址低字节 | 3 | 线圈起始地址低位 |
| 线圈数量高字节 | 4 | 线圈数量高位 |
| 线圈数量低字节 | 5 | 线圈数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
此功能码用于写入从机的多个保持寄存器值。
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x10 |
| 起始地址高字节 | 2 | 寄存器起始地址高位 |
| 起始地址低字节 | 3 | 寄存器起始地址低位 |
| 寄存器数量高字节 | 4 | 要写的寄存器数量高位 |
| 寄存器数量低字节 | 5 | 要写的寄存器数量低位 |
| 字节数 | 6 | 后续数据字节数(寄存器数×2) |
| 寄存器值 | 7-n | 寄存器值数据(每个寄存器占2个字节) |
| CRC低字节 | n+1 | CRC校验低位 |
| CRC高字节 | n+2 | CRC校验高位 |
| 字段 | 字节索引 | 描述 |
|---|---|---|
| 设备地址 | 0 | 从机地址 |
| 功能码 | 1 | 0x10 |
| 起始地址高字节 | 2 | 寄存器起始地址高位 |
| 起始地址低字节 | 3 | 寄存器起始地址低位 |
| 寄存器数量高字节 | 4 | 寄存器数量高位 |
| 寄存器数量低字节 | 5 | 寄存器数量低位 |
| CRC低字节 | 6 | CRC校验低位 |
| CRC高字节 | 7 | CRC校验高位 |
当发生错误时,从机会返回异常响应,功能码最高位置1,并附带异常码:
| 异常码 | 含义 | 描述 |
|---|---|---|
| 01 (0x01) | ILLEGAL FUNCTION | 功能码不支持 |
| 02 (0x02) | ILLEGAL DATA ADDRESS | 数据地址无效 |
| 03 (0x03) | ILLEGAL DATA VALUE | 数据值无效 |
| 04 (0x04) | SLAVE DEVICE FAILURE | 从机设备故障 |
| 05 (0x05) | ACKNOWLEDGE | 确认 |
| 06 (0x06) | SLAVE DEVICE BUSY | 从机设备忙 |
| 08 (0x08) | MEMORY PARITY ERROR | 存储奇偶校验错误 |
| 10 (0x0A) | GATEWAY PATH UNAVAILABLE | 网关路径不可用 |
| 11 (0x0B) | GATEWAY TARGET DEVICE FAILED TO RESPOND | 网关目标设备无响应 |
| 字段 | 描述 |
|---|---|
| 设备地址 | 从机地址 |
| 功能码 | 原功能码+0x80 |
| 异常码 | 异常类型 |
| CRC | CRC校验 |
Modbus RTU使用16位循环冗余校验(CRC)来检测传输错误。
主机请求读取设备地址为1的从机,起始地址为0x0030的5个保持寄存器:
从机响应返回5个寄存器的值:
主机请求将设备地址为1的从机,地址为0x0002的保持寄存器设置为0x01F4:
从机响应确认写入成功: