|
@@ -1,74 +1,147 @@
|
|
|
-# modbus协议
|
|
|
|
|
|
|
+# modbus.org的协议规范
|
|
|
|
|
|
|
|
-##### modbus rtu 、modbus tcp、modbus ascii区别
|
|
|
|
|
|
|
+**modbus协议规范: https://modbus.org/specs.php**
|
|
|
|
|
|
|
|
-ModBus协议是应用层报文传输协议(OSI模型第7层),它定义了一个与通信层无关的协议数据单元(PDU),即PDU=功能码+数据域。
|
|
|
|
|
-ModBus协议能够应用在不同类型的总线或网络。对应不同的总线或网络,Modbus协议引入一些附加域映射成应用数据单元(ADU),即ADU=附加域+PDU。目前,Modbus有下列三种通信方式:
|
|
|
|
|
|
|
+**原文翻译:**
|
|
|
|
|
|
|
|
-modbus rtu : 数据是按byte传输,一般通过串口RS232/RS422/RS485传输、也可以通过tcp/udp等其他介质。
|
|
|
|
|
|
|
+MODBUS 是一种应用层消息协议,位于 OSI 模型的第 7 层。它在不同类型的总线或网络上连接的设备之间提供客户端/服务器通信。
|
|
|
|
|
|
|
|
-modbus tcp : 数据是按byte传输,一般通过tcp/udp传输。
|
|
|
|
|
|
|
+作为事实上的工业串行标准,自 1979 年以来,MODBUS 继续支持数百万自动化设备进行通信。今天,对 MODBUS 简单而优雅的结构的支持继续增长。Internet 社区可以在 TCP/IP 堆栈上保留的系统端口 502 上访问 MODBUS。
|
|
|
|
|
|
|
|
-modbus ascii : 数据是按十六进制字符表示,传输介质与rtu一样。
|
|
|
|
|
|
|
+MODBUS 是一种请求/应答协议,提供由功能代码指定的服务。MODBUS 功能代码是 MODBUS 请求/回复 PDU 的元素。该协议规范文档描述了在 MODBUS 事务框架内使用的功能代码。
|
|
|
|
|
|
|
|
|
|
+[**MODBUS 协议规范**](https://modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf)
|
|
|
|
|
|
|
|
|
|
+本文档为 Modbus 应用协议 V1.1b3。它描述了在 MODBUS 事务框架内使用的功能代码。
|
|
|
|
|
|
|
|
-### modbus PDU
|
|
|
|
|
|
|
+[**MODBUS 安全协议**](https://modbus.org/docs/MB-TCP-Security-v21_2018-07-24.pdf)
|
|
|
|
|
|
|
|
-| 功能码 | 数据区域 |
|
|
|
|
|
-| ------------- | -------- |
|
|
|
|
|
-| function code | data |
|
|
|
|
|
|
|
+Modbus 安全协议通过将传输层安全 (TLS) 与传统 Modbus 协议相结合来提供保护。TLS 封装 Modbus 数据包以提供身份验证和消息完整性保护。新协议还利用 X.509v3 数字证书对服务器和客户端进行身份验证。新的 Modbus 安全协议使用端口 802。
|
|
|
|
|
|
|
|
-###
|
|
|
|
|
|
|
+[**仅适用于传统应用的串行线路上的 MODBUS**](https://modbus.org/docs/PI_MBUS_300.pdf)
|
|
|
|
|
|
|
|
-### modbus rtu
|
|
|
|
|
|
|
+这是 1996 年过时的 Modbus 规范。仅用于解决遗留问题。请不要将它用于新的实现。
|
|
|
|
|
|
|
|
-| 从站地址 | 功能码 | 数据区 | CRC校验 |
|
|
|
|
|
-| -------- | ------ | -------------------- | --------- |
|
|
|
|
|
-| 1byte | 1byte | 0-252byte | 2byte |
|
|
|
|
|
-| 0x01 | 0x01 | 0x00 0x00 0x00 0x01 | 0xFD 0xCA |
|
|
|
|
|
-| 0x01 | 0x01 | 0x01 0x00 | 0x51 0x88 |
|
|
|
|
|
-| 0x01 | 0x03 | 0x00 0x00 0x00 0x01 | 0x84 0x0A |
|
|
|
|
|
-| 0x01 | 0x03 | 0x02 0x00 0x00 | 0xB8 0x44 |
|
|
|
|
|
|
|
+[**Modbus 串行线路协议和实施指南 V1.02**](https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf)请将此用于新的 MODBUS 实施。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-### modbus tcp
|
|
|
|
|
|
|
|
|
|
-| 报文头 | 功能码 | 数据区 |
|
|
|
|
|
-| ----------------------------------- | ------ | ------------------- |
|
|
|
|
|
-| 7byte | 1byte | 0-252byte |
|
|
|
|
|
-| 0x00 0x00 0x00 0x00 0x00 0x06 0x01 | 0x01 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
-| 0x00 0x01 0x00 0x00 0x00 0x04 0x01 | 0x01 | 0x01 0x00 |
|
|
|
|
|
-| 0x00 0x02 0x00 0x00 0x00 0x06 0x01 | 0x02 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
-| 0x00 0x02 0x00 0x00 0x00 0x04 0x01 | 0x02 | 0x01 0x00 |
|
|
|
|
|
-| 0x00 0x03 0x00 0x00 0x00 0x06 0x01 | 0x03 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
-| 0x00 0x03 0x00 0x00 0x00 0x05 0x01 | 0x03 | 0x02 0x00 0x00 |
|
|
|
|
|
|
|
|
|
|
|
|
+# modbus rtu tcp ascii 的区别
|
|
|
|
|
|
|
|
|
|
+ModBus协议是应用层报文传输协议(OSI模型第7层),它定义了一个与通信层无关的
|
|
|
|
|
|
|
|
-### modbus ascii
|
|
|
|
|
|
|
+协议数据单元(PDU),即 **PDU=功能码+数据域**。
|
|
|
|
|
|
|
|
-| 报文头 | 从站地址 | 功能码 | 数据区 | LRC校验 | 报文尾 |
|
|
|
|
|
-| ------- | ------------- | ------------- | --------- | ------- | --------------- |
|
|
|
|
|
-| 1byte | 2byte | 2byte | 0-252byte | 2byte | 2byte |
|
|
|
|
|
-| :(0x3A) | 01(0x30,0x31) | 01(0x30,0x31) | ... | | \n\r(0x0D,0x0A) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ModBus协议能够应用在不同类型的总线或网络。
|
|
|
|
|
+
|
|
|
|
|
+对应不同的总线或网络,Modbus协议引入一些附加域映射成
|
|
|
|
|
+
|
|
|
|
|
+应用数据单元(ADU),即 **ADU=附加域+PDU**。
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+| modbus应用层 | modbus rtu | modbus tcp | modbus ascii |
|
|
|
|
|
+| ----------------- | ---------------------- | --------------------------- | ---------------------- |
|
|
|
|
|
+| modbus协议栈 | master主机 slave从机 | master主机 slave从机 | master主机 slave从机 |
|
|
|
|
|
+| 协议数据单元(PDU) | 功能码+数据域 | 功能码+数据域 | 功能码+数据域 |
|
|
|
|
|
+| 应用数据单元(ADU) | 地址码+PDU+CRC校验码 | MBAP+PDU | 地址码+PDU+CRC校验码 |
|
|
|
|
|
+| | | | |
|
|
|
|
|
+| 表示层 | 无 | tcp/ip | 无 |
|
|
|
|
|
+| 会话层 | 无 | tcp/ip | 无 |
|
|
|
|
|
+| 传输层 | 无 | tcp/ip | 无 |
|
|
|
|
|
+| 网络层 | 无 | 三层交换机/路由器/tcp/ip | 无 |
|
|
|
|
|
+| 数据链路层 | modbus 串行协议 (串口) | 二层交换机/以太网/WLAN/网卡 | modbus 串行协议 (串口) |
|
|
|
|
|
+| 物理链路层 | RS232/RS485/RS422 | 中继器/集线器/双绞线 | RS232/RS485/RS422 |
|
|
|
|
|
+| | | | |
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+modbus rtu 的 **地址码**:
|
|
|
|
|
+
|
|
|
|
|
+| 0 | 1 - 247 | 248-255 |
|
|
|
|
|
+| -------- | ------------------ | -------- |
|
|
|
|
|
+| 广播地址 | 从机地址可用的地址 | 保留地址 |
|
|
|
|
|
+| | | |
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+modbus rtu 的 **CRC校验码**: 使用crc16 rtu算法
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------------- | ------- | -------------- |
|
|
|
|
|
+| CRC16 LOW BYTE | 1 Bytes | CRC16低8位字节 |
|
|
|
|
|
+| CRC16 HIGH BYTE | 1 Bytes | CRC16高8位字节 |
|
|
|
|
|
+| | | |
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+modbus tcp 的 **MBAP**: modbus应用协议头(MODBUS Application Protocol header ),下表表示具体格式
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 | Client(master)主机 | Server(slave)从机 |
|
|
|
|
|
+| ---------------------- | ------- | --------------- | ---------------------- | ------------------- |
|
|
|
|
|
+| Transaction Identifier | 2 Bytes | 请求的ID | 初始化为0,每次请求加1 | 保持跟主机请求一致 |
|
|
|
|
|
+| Protocol Identifier | 2 Bytes | 0表示modbus协议 | 初始化为0 | 保持跟主机请求一致 |
|
|
|
|
|
+| Length | 2 Bytes | 表示PDU部分长度 | | 保持跟主机请求一致 |
|
|
|
|
|
+| Unit Identifier | 1 Byte | | | 保持跟主机请求一致 |
|
|
|
|
|
+| | | | | |
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# modbus 线圈和寄存器
|
|
|
|
|
+
|
|
|
|
|
+**线圈寄存器区别:**
|
|
|
|
|
+
|
|
|
|
|
+| | 保持线圈 | 输入线圈 | 保持寄存器 | 输入寄存器 |
|
|
|
|
|
+| ---------------- | ------------- | ------------ | ----------------- | --------------- |
|
|
|
|
|
+| | HOLDING_COILS | INPUTS_COILS | HOLDING_REGISTERS | INPUT_REGISTERS |
|
|
|
|
|
+| 可表示值范围 | 开关量 0/1 | 开关量 0/1 | 模拟量 0-65535 | 模拟量 0-65535 |
|
|
|
|
|
+| 读取功能码 | 0x01 | 0x02 | 0x03 | 0x04 |
|
|
|
|
|
+| 写功能码 | 0x05 / 0x0F | 只读,不可写 | 0x06 / 0x10 | 只读,不可写 |
|
|
|
|
|
+| 单次可读最大数量 | 2000 | 2000 | 125 | 125 |
|
|
|
|
|
+| 单次可写最大数量 | 1 / 1968 | 0 | 1 / 123 | 0 |
|
|
|
|
|
+| | | | | |
|
|
|
|
|
+
|
|
|
|
|
+**保持线圈:**
|
|
|
|
|
+
|
|
|
|
|
+一个单位只有1bit,只有1,0两个状态,可读可写.一般用来表示可控制的数字量,比如继电器,灯,电源开关等等。
|
|
|
|
|
+
|
|
|
|
|
+**输入线圈:**
|
|
|
|
|
+
|
|
|
|
|
+一个单位只有1bit,只有1,0两个状态,只能读.一般用来表示输入的数字量,开关,数字量传感器等等。
|
|
|
|
|
+
|
|
|
|
|
+**保持寄存器:**
|
|
|
|
|
+
|
|
|
|
|
+一个单位只有16bit,可以表示0-65535,可读可写. 一般用来表示可控制的模拟量,DAC模拟量输出设备 等等。
|
|
|
|
|
+
|
|
|
|
|
+**输入寄存器:**
|
|
|
|
|
+
|
|
|
|
|
+一个单位只有16bit,可以表示0-65535,只能读. 一般用来表示输入的模拟量,ADC采集值,模拟量传感器的ADC值等等。
|
|
|
|
|
|
|
|
-### 线圈/寄存器:
|
|
|
|
|
|
|
|
|
|
-##### 线圈 coil : 保持线圈、输入线圈
|
|
|
|
|
|
|
|
|
|
-一个单位只有1bit,只有1,0两个状态。保持线圈可读可写,输入线圈只能读。
|
|
|
|
|
|
|
+可多个单位的寄存器组合成一个值。比如:
|
|
|
|
|
|
|
|
-##### 寄存器register: 保持寄存器、输入寄存器
|
|
|
|
|
|
|
+2个寄存器组合起来数据宽度是32bit可以表示一个int型的值,也可以表示一个单精度浮点型float的值。
|
|
|
|
|
|
|
|
- 一个单位只有16bit,可以表示0-4095。保持寄存器可读可写,输入寄存器只能读。
|
|
|
|
|
|
|
+4个寄存器组合起来数据宽度是64bit可以表示一个双精度浮点型double的值。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-### 常用功能码:
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# modbus 读写流程
|
|
|
|
|
+
|
|
|
|
|
+ **常用功能码:**
|
|
|
|
|
|
|
|
| 功能码 | 名称 | 可操作最大数量 |
|
|
| 功能码 | 名称 | 可操作最大数量 |
|
|
|
| ------ | ----------------------------------------- | -------------- |
|
|
| ------ | ----------------------------------------- | -------------- |
|
|
@@ -85,121 +158,186 @@ modbus ascii : 数据是按十六进制字符表示,传输介质与rtu一样
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-# modbus流程
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
-##### 主机(master)查询 poll
|
|
|
|
|
|
|
|
|
|
-(主机) ---查询---> (从机) ---应答---> (主机)
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+### master请求 读线圈 0x01 0x02
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | ------------ |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x01 或 0x02 |
|
|
|
|
|
+| 线圈地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 线圈个数 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+
|
|
|
|
|
+### slave应答 读线圈 0x01 0x02
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | ----------------------------------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x01 或 0x02 |
|
|
|
|
|
+| 数据长度 | 1 Bytes | 数据值等于 = (线圈个数/ 8) + ((线圈个数% 8) ? 1 : 0) |
|
|
|
|
|
+| 线圈数据 | n Bytes | 1个字节表示8个线圈状态 |
|
|
|
|
|
+
|
|
|
|
|
+###
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+### master请求 读寄存器 0x03 0x04
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | ------------ |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x03 或 0x04 |
|
|
|
|
|
+| 寄存器地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 寄存器个数 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+
|
|
|
|
|
+### slave应答 读寄存器 0x03 0x04
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | ------------------------------------ |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x03 或 0x04 |
|
|
|
|
|
+| 数据长度 | 1 Bytes | 数据值等于 = (寄存器个数×2) |
|
|
|
|
|
+| 寄存器数据 | n Bytes | 高字节在前,2个字节表示1个寄存器状态 |
|
|
|
|
|
+
|
|
|
|
|
+###
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+### master请求 写单个线圈 0x05
|
|
|
|
|
+
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | ---------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x05 |
|
|
|
|
|
+| 线圈地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 线圈状态 | 2 Bytes | 0x0000表示0,其他表示1 |
|
|
|
|
|
|
|
|
-##### 从机(slave)等待查询 wait
|
|
|
|
|
|
|
+### slave应答 写单个线圈 0x05
|
|
|
|
|
|
|
|
-(从机) ---等待主机查询---> 处理数据 ---应答---> (主机)
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | -------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x05 |
|
|
|
|
|
+| 线圈地址 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
+| 线圈状态 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+###
|
|
|
|
|
|
|
|
-查询: 读线圈、读寄存器、写线圈、写寄存器、读从机地址、读错误码
|
|
|
|
|
|
|
|
|
|
-应答: 正常应答、错误应答
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+### master请求 写多个线圈 0x0F
|
|
|
|
|
|
|
|
-### 0x01、0x02 读线圈 PDU格式
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | ----------------------------------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x0F |
|
|
|
|
|
+| 线圈地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 线圈个数 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 数据长度 | 1 Bytes | 数据值等于 = (线圈个数/ 8) + ((线圈个数% 8) ? 1 : 0) |
|
|
|
|
|
+| 线圈数据 | n Bytes | 1个字节表示8个线圈状态 |
|
|
|
|
|
|
|
|
-| 功能码 | 起始线圈地址 | 线圈个数 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
+### slave应答 写多个线圈 0x0F
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| -------- | ------- | -------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x0F |
|
|
|
|
|
+| 线圈地址 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
+| 线圈个数 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
|
|
|
-| 功能码 | 数据长度 | 数据(1bit表示一个线圈) |
|
|
|
|
|
-| ------ | -------- | ------------------------ |
|
|
|
|
|
-| 1byte | 1byte | 数据长度 |
|
|
|
|
|
|
|
+###
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-### 0x03、0x04 读寄存器 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 起始寄存器地址 | 寄存器个数 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 数据长度 | 数据(16bit表示一个寄存器) |
|
|
|
|
|
-| ------ | -------- | --------------------------- |
|
|
|
|
|
-| 1byte | 1byte | 数据长度 |
|
|
|
|
|
|
|
+### master请求 写单个寄存器 0x06
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | ---------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x06 |
|
|
|
|
|
+| 寄存器地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 寄存器状态 | 2 Bytes | 高字节在前 |
|
|
|
|
|
|
|
|
|
|
+### slave应答 写单个寄存器 0x06
|
|
|
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | -------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x06 |
|
|
|
|
|
+| 寄存器地址 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
+| 寄存器状态 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
|
|
|
-### 0x05写单个线圈 PDU格式
|
|
|
|
|
|
|
+###
|
|
|
|
|
|
|
|
-| 功能码 | 起始线圈地址 | 状态数据 |
|
|
|
|
|
-| ------ | ---------------- | -------------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte( 高字节有效) |
|
|
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 起始线圈地址 | 状态数据 |
|
|
|
|
|
-| ------ | ---------------- | --------------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte ( 高字节有效) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+### master请求 写多个寄存器 0x10
|
|
|
|
|
|
|
|
-### 0x0F 写多个线圈 PDU格式
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | ------------------------------------ |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x10 |
|
|
|
|
|
+| 寄存器地址 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 寄存器个数 | 2 Bytes | 高字节在前 |
|
|
|
|
|
+| 数据长度 | 1 Bytes | 数据值等于 = (寄存器个数X2) |
|
|
|
|
|
+| 寄存器数据 | n Bytes | 高字节在前,2个字节表示1个寄存器状态 |
|
|
|
|
|
|
|
|
-| 功能码 | 起始线圈地址 | 线圈个数 | 数据长度 | 数据(一个线圈占1bit) |
|
|
|
|
|
-| ------ | ---------------- | ---------------- | -------- | -------------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 | 1byte | 数据长度 |
|
|
|
|
|
|
|
+### slave应答 写多个线圈 0x0F
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
+| 名称 | 长度 | 描述 |
|
|
|
|
|
+| ---------- | ------- | -------------------------- |
|
|
|
|
|
+| 功能码 | 1 Bytes | 0x10 |
|
|
|
|
|
+| 寄存器地址 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
+| 寄存器个数 | 2 Bytes | 高字节在前,跟请求保持一致 |
|
|
|
|
|
|
|
|
-| 功能码 | 起始线圈地址 | 线圈个数 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
+###
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
-### 0x06 写单个寄存器 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 起始寄存器地址 | 数据 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 起始寄存器地址 | 数据 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
+### modbus rtu格式样例
|
|
|
|
|
|
|
|
|
|
+| 从站地址 | 功能码 | 数据区 | CRC校验 |
|
|
|
|
|
+| -------- | ------ | -------------------- | --------- |
|
|
|
|
|
+| 1byte | 1byte | 0-252byte | 2byte |
|
|
|
|
|
+| 0x01 | 0x01 | 0x00 0x00 0x00 0x01 | 0xFD 0xCA |
|
|
|
|
|
+| 0x01 | 0x01 | 0x01 0x00 | 0x51 0x88 |
|
|
|
|
|
+| 0x01 | 0x03 | 0x00 0x00 0x00 0x01 | 0x84 0x0A |
|
|
|
|
|
+| 0x01 | 0x03 | 0x02 0x00 0x00 | 0xB8 0x44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
-### 0x10 写多个寄存器 PDU格式
|
|
|
|
|
|
|
|
|
|
-| 功能码 | 起始寄存器地址 | 寄存器个数 | 数据长度 | 数据(一个寄存器占16bit) |
|
|
|
|
|
-| ------ | ---------------- | ---------------- | -------- | ----------------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 | 1byte | 数据长度 |
|
|
|
|
|
|
|
+### modbus tcp格式样例
|
|
|
|
|
|
|
|
-##### 应答 PDU格式
|
|
|
|
|
|
|
+| 报文头 | 功能码 | 数据区 |
|
|
|
|
|
+| ----------------------------------- | ------ | ------------------- |
|
|
|
|
|
+| 7byte | 1byte | 0-252byte |
|
|
|
|
|
+| 0x00 0x00 0x00 0x00 0x00 0x06 0x01 | 0x01 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
+| 0x00 0x01 0x00 0x00 0x00 0x04 0x01 | 0x01 | 0x01 0x00 |
|
|
|
|
|
+| 0x00 0x02 0x00 0x00 0x00 0x06 0x01 | 0x02 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
+| 0x00 0x02 0x00 0x00 0x00 0x04 0x01 | 0x02 | 0x01 0x00 |
|
|
|
|
|
+| 0x00 0x03 0x00 0x00 0x00 0x06 0x01 | 0x03 | 0x00 0x00 0x00 0x01 |
|
|
|
|
|
+| 0x00 0x03 0x00 0x00 0x00 0x05 0x01 | 0x03 | 0x02 0x00 0x00 |
|
|
|
|
|
|
|
|
-| 功能码 | 起始寄存器地址 | 寄存器个数 |
|
|
|
|
|
-| ------ | ---------------- | ---------------- |
|
|
|
|
|
-| 1byte | 2byte 高字节在前 | 2byte 高字节在前 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+### modbus ascii格式样例
|
|
|
|
|
+
|
|
|
|
|
+| 报文头 | 从站地址 | 功能码 | 数据区 | LRC校验 | 报文尾 |
|
|
|
|
|
+| ------- | ------------- | ------------- | --------- | ------- | --------------- |
|
|
|
|
|
+| 1byte | 2byte | 2byte | 0-252byte | 2byte | 2byte |
|
|
|
|
|
+| :(0x3A) | 01(0x30,0x31) | 01(0x30,0x31) | ... | | \n\r(0x0D,0x0A) |
|
|
|
|
|
+
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -207,7 +345,33 @@ modbus ascii : 数据是按十六进制字符表示,传输介质与rtu一样
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+# CRC16 A001 算法
|
|
|
|
|
|
|
|
|
|
+```c
|
|
|
|
|
+uint16_t modbus_crc16(uint8_t *buffer, uint16_t buffer_length)
|
|
|
|
|
+{
|
|
|
|
|
+ uint16_t CRC= 0XFFFF;
|
|
|
|
|
+ uint16_t CRC_count = 0;
|
|
|
|
|
+ uint16_t i = 0;
|
|
|
|
|
+ for(CRC_count=0;CRC_count< buffer_length ; CRC_count++)
|
|
|
|
|
+ {
|
|
|
|
|
+ CRC= CRC^ *(buffer+CRC_count);
|
|
|
|
|
+ for(i=0;i<8;i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if(CRC&1)
|
|
|
|
|
+ {
|
|
|
|
|
+ CRC>>=1;
|
|
|
|
|
+ CRC^=0xA001;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ CRC>>=1;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return CRC;
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|