找回密码
 立即注册
首页 业界区 安全 Modbus 协议 学习一则

Modbus 协议 学习一则

郗燕岚 昨天 23:20
Modbus 协议

一文学习 了解 OSI模型、TCP/IP模型、网络封包
Modbus 是一种通信协议,用于在工业自动化领域中的设备之间进行数据交换。它是一种简单而广泛使用的串行通信协议,用于将控制设备(如传感器、执行器、PLC等)与监控设备(如计算机、远程终端等)连接起来。
Modbus RTU、ASCII、TCP 的区别

Modbus的协议版本 包括Modbus RTU、Modbus ASCII、Modbus TCP/IP、Modbus UDP/IP等

  • Modbus RTU与Modbus ASCII,都使用串口通讯协议,Modbus RTU使用二进制格式进行数据传输,通讯效率更高,Modbus ASCII使用ASCII码进行数据传输,可读性好,但通讯效率更低。
  • Modbus TCP/IP是基于以太网的一种通讯方式,它将Modbus协议封装在TCP/IP协议栈中,通过以太网传输数据。具有高速、稳定的特点。
  • Modbus UDP/IP是基于UDP/IP协议的一种通讯方式
Modbus RTU使用二进制编码进行通信,而Modbus ASCII则使用可打印的ASCII字符。Modbus RTU是更常用的版本,因为它在数据传输效率方面更高。
Modbus协议采用主从结构,其中一个设备充当主站(主机),负责发起通信请求和控制操作,而其他设备则充当从站(从机),接收主站的请求并提供数据。只能主站发起请求,从站不能,发起请求
Modbus 结构

1. 数据传输格式

协议类型数据编码帧结构示例RTU二进制紧凑的二进制数据,直接传输十六进制字节(如 0x01)。[01][03][00][01][00][01][D5][CA]​ASCIIASCII字符数据转换为可读的ASCII字符(如 "0" → 0x30),每字节拆分为两个ASCII字符。:010300010001D5CA​TCP二进制(基于TCP)​在TCP/IP协议栈上传输,添加MBAP头(Modbus Application Protocol header)。0001000000060103000100012. 帧结构与分隔符

协议类型帧起始符帧结束符校验方式字节间隔要求RTU无无CRC(2字节)严格时间间隔(3.5字符)​ASCII:(冒号)CR+LF(回车换行)LRC(纵向冗余校验)无严格间隔要求​TCPMBAP头通过TCP包长度标识无额外校验(依赖TCP/IP校验)无间隔要求3. 传输效率

协议类型效率RTU:二进制编码,数据紧凑,适合低速串行链路(如RS-485)。​ASCII:每个字节需转换为2个ASCII字符(如0xA1→"A""1"),传输数据量翻倍。​TCP:基于TCP/IP,支持高速网络,但需额外添加MBAP头(7字节)。4. 校验方式

协议类型校验机制校验范围RTUCRC-16​(循环冗余校验)整个数据帧(地址+功能码+数据)​ASCIILRC​(纵向冗余校验,1字节)数据字段(不包含起始/结束符)​TCP依赖TCP/IP校验​(无额外Modbus层校验)TCP/IP协议栈自动校验

  • RTU / CRC-16-IBM
    CRC-16的算法有多种变种,Modbus使用的是CRC-16-IBM
    以 0x01,0x03,0x00,0x00,0x00,0x08,0x44,0x0C的 0x3 请求为例 其中0x01,0x03,0x00,0x00,0x00,0x08 的CRC-16 (Modbus) 实际计算工具检验码是(0x440C)
    按大端序输出​​:高字节 0x0C → 0x44
  1. byte[] data = {0x01,0x03,0x00,0x00,0x00,0x08};
复制代码
crc-calculation - https://www.lammertbies.nl/comm/info/crc-calculation
5. 物理接口

协议类型传输介质典型速率应用场景RTURS-485/RS-2321.2kbps - 115.2kbps工业现场设备(PLC、传感器)​ASCIIRS-485/RS-232低于RTU(因效率低)调试场景(数据可读性强)​TCP以太网(TCP/IP)10Mbps - 1Gbps工厂局域网、SCADA系统远程通信数据帧格式

无论哪一种Modbus协议版本的帧格式都是一样的
数据帧部分描述占用字节设备地址(Slave ID)识别从站的唯一地址1字节功能码(Function Code)主机对从机实现的操作,功能码1字节数据区(Data Field)包含功能码所需的数据或返回的数据可变错误校验(CRC)循环冗余校验,用于错误检测2字节
主站发出的功能码 01 ~ 06 的请求时, 数据一定的8个字节(数据区使用1个字节表示开始地址, 1个字节表示长度)
数据/地址类型

Modbus中定义的四种数据类型

  • 离散输出(Discrete Outputs):

    • 这些寄存器也称为线圈(Coils),它们代表二进制输出(0 或 1),通常用于控制开关设备。
    • 地址范围通常是 0x00001 到 0xFFFFF(Modbus TCP)或 0x0000 到 0xFFFF(Modbus RTU/ASCII)。
    • 功能码 01(读取线圈状态)和 05(写入单个线圈)用于离散输出。

  • 离散输入(Discrete Inputs):

    • 这些寄存器代表二进制输入状态,它们是只读的,通常用于表示传感器或开关的状态。
    • 地址范围通常是 0x10001 到 0x1FFFF(Modbus TCP)或 0x0001 到 0xFFFF(Modbus RTU/ASCII)。
    • 功能码 02(读取离散输入状态)用于离散输入。

  • 保持寄存器(Holding Registers):

    • 这些寄存器用于存储可读写的数值数据,通常用于表示过程变量,如温度或压力。
    • 地址范围通常是 0x40001 到 0x4FFFF(Modbus TCP)或 0x0000 到 0xFFFF(Modbus RTU/ASCII)。
    • 功能码 03(读取保持寄存器)和 06(写入单个保持寄存器)用于保持寄存器。

  • 输入寄存器(Input Registers):

    • 这些寄存器用于存储只读数值数据,通常用于表示模拟量输入,如电流或电压。
    • 地址范围通常是 0x30001 到 0x3FFFF(Modbus TCP)或 0x0000 到 0xFFFF(Modbus RTU/ASCII)。
    • 功能码 04(读取输入寄存器)用于输入寄存器。

功能码

​功能码(十六进制)​​​​名称​​​​操作类型​​​​访问权限​​​​PLC 地址范围​​​​数据类型​​​​0x01​读取线圈状态(Read Coils)位操作读00001-09999(0x地址)二进制位(ON/OFF)​​0x02​​读取离散输入状态(Read Discrete Inputs)位操作读10001-19999(1x地址)二进制位(ON/OFF)​​0x03​​读取保持寄存器(Read Holding Registers)字操作读40001-49999(4x地址)16位整数/浮点数​​0x04​​读取输入寄存器(Read Input Registers)字操作读30001-39999(3x地址)16位整数/浮点数​​0x05​​写单个线圈(Write Single Coil)位操作写00001-09999(0x地址)二进制位(ON/OFF)​​0x06​​写单个保持寄存器(Write Single Register)字操作写40001-49999(4x地址)16位整数/浮点数​​0x0F​​写多个线圈(Write Multiple Coils)位操作写00001-09999(0x地址)二进制位(ON/OFF)​​0x10​​写多个保持寄存器(Write Multiple Registers)字操作写40001-49999(4x地址)16位整数/浮点数​​0x07​​读取异常状态(Read Exception Status)位操作读由设备定义(内部线圈)二进制位(ON/OFF)​​0x08​​回送诊断校验(Diagnostics)诊断操作读/写无特定地址诊断数据Modbus功能码占用一个字节,取值范围是1127(即0x010x7F)。同时,使用功能码+0x80表示异常状态,即129~255代表异常码。
在Modbus标准协议中,一共规定了三类Modbus功能码。

  • 公共功能码
    。被明确定义的功能码;
    。保证唯一性;
    。由Modbus协会确认,并提供公开的文档:
    。可进行一致性测试:
    。包括协议定义的功能码和保留将来使用的功能码。
  • 用户自定义功能码
    。有两个用户自定义功能码区域,分别是6572和100110;
    。用户自定义,不保证唯一性。
  • 保留功能码
    。保留功能码是因为历史遗留原因,某些公司的传统产品上现行使用的功能码不作为公共使用。
实际最常用的是公共功能码中的4个功能码:03/04/06/10
实例

主站发送

主站向从站发送的实际请求数据帧:03 04 00 08 00 01 B0 3B (假设从站地址为03)
其中:
03:为主站要访问的域名(即从站地址,范围0~247)。
04:表示功能码。
00 08:表示从从站寄存器08这个地址开始读取数据。
00 01:表示从站寄存器, 读取数据的长度。(这里即读取一个字节)
b0 3b:两个字节的校验数据。(Modbus CRC)
从站响应

从站接收到主站的请求数据帧之后实际的响应数据帧为:03 04 02 00 0A 40 F7
其中:
03:为从站地址即域名(即从站地址,范围0~247)。(主站发送什么就响应什么)
04:表示功能码。(主站发送什么就响应什么)
02:被读取数据长度(所以最多 255 - 4  字节? 253字节)
00 0A:被读取的具体数据
40 F7:两个字节的校验数据
协议限制


  • Modbus协议报文(两个帧的)间隔需要大于3.5个字符计算:
    1.1、有检验位
    1个字符=1(起始位)+8(数据位)+1(奇偶校验位)+1(停竖位)=11位3.5个字符=3.511=38.5位
    如果波特率=9600bps,则3.5个字符间隔时间为 38.5/9.6=4.0104167ms : 字节间间隔时间=1.5
    字符间隔时间 ≈2.6042ms
    1.2 无校验位
    1个字符=1(起始位)+8(数据位)+0(无校验位)+1(停止位)=10位
    3.5个字符=3.5*10=35位
    如果波特率=9600bps,则3.5个字符间隔时间为35/9.6=3.6458毫秒
  • 通常可以将传输 45位的时间四舍五入后做为报文时间间隔。
    如果波特率=9600bps,则45位传输时间为45/9.6=4.6875≈5毫秒

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册