ModBud_RTU协议

目录

ModBus概述

ModBus协议常见类型

ModBud RTU

工作方式

断帧方式

完整通讯流程图

帧格式

通讯流程

主设备读流程

主设备写流程

Java 中常用的 Modbus库

外部链接


ModBus概述

Modbus 是一种串行通讯协议,是 Modicon 公司(已被施耐德电气 Schneider Electric 收购)于 1979 年为使用可编程逻辑控制器PLC)通信而发表。Modbus 已经成为工业领域通信协议事实上的业界标准,并且现在是工业电子设备之间常用的连接方式。Modbus 比其他通信协议使用的更广泛的主要原因有:

  • 公开发表并且无著作权要求
  • 易于部署和维护
  • 对供应商来说,修改移动本地的比特或字节没有很多限制

ModBus协议常见类型

Modbus 协议当前存在用于串口、以太网以及其他支持互联网协议的网络的版本。

大多数 Modbus 设备通信通过串口 EIA-485、RS232 物理层进行。

对于串行连接,存在两个变种,他们分别是 ModBus ASCII ModBus RTU 。它们在数值数据表示和协议细节上略有不同。Modbus RTU 是一种紧凑的,采用二进制表示数据的方式,Modbus ASCII 是一种人类可读的,冗长的表示方式。这两个变种都使用串行通信(serial communication)方式。

RTU 格式后续的命令/数据带有 CRC 的校验和,而 ASCII 格式采用 纵向冗余校验 的校验和。

此外,ASCII 格式有 特殊的帧头 :ASCII 3AH)和 结束标志 回车换行符(ASCII 0DH,0AH

对于通过 TCP/IP 的连接,存在多个 Modbus/TCP 变种,由于 TCP 是可靠的(三次握手四次挥手,维持在线,重传机制),因此这种方式不需要再增加 校验和 计算。

Modbus TCP帧格式可查看:modbus tcp 数据报文结构

ModBud RTU

工作方式

Modbus 是一个主/从协议,该协议规定,通讯设备分为主设备和从设备。

1
标准的ModBus通讯拓扑

Modbus RTU 中有一个主设备,最多可以有 247 个从设备。 每个从设备由从地址 1 247 标识。

主机

主机可连接多个从机,在 ModBus RTU 协议中,从机地址有 8bit,其中 0x00 作为广播地址,0x01 ~ 0xF7(1 ~ 247)作为从机地址,剩余 8 个地址为协议保留。回到正题,主机可以从从机获取信息(读寄存器),亦可以写入信息到从机(写寄存器)。

自动化生产系统中的中央控制器就是典型的 Modbus主机。

从机

Modbus RTU 从机 是响应主机请求的设备。 从机接收到主机请求,一般的处理方式有两种:积极响应(分析请求并执行相应的动作),异常响应(CRC校验出错等)。

注意:

上文提及的寄存器并非真的寄存器,而是一个抽象的概念,表征某类数据,例如:温度,湿度

所以通讯必须由主设备发起,没有办法要求从设备 “报告异常”(构建在以太网的 TCP/IP 协议之上,被称为 open-mbus 除外)主设备必须循环的询问每个从设备,并查找数据中的变化。在带宽可能比较宝贵的应用中,这种方式在应用中消耗带宽和网络时间,例如在低速率的无线链路上。

 

若将 ModBus 应用与无线传输上,则需额外考虑以下问题

  • 由于我们将 ModBus 协议帧通过无线传输,那么我们的 ModBus 协议帧需要满足无线通讯的协议。以 BLE 为例,BLE数据是通过特征值发送出去的,每个特征值有 20byte ,故而当 ModBus 协议总长度 大于20byte 时,我们需要采取数据分包的策略,即将 一个 ModBus协议帧 拆分成 多个 Modbus协议帧 发送。否则从机收到的数据是断帧的,这就需要从机将断帧重新组合成 完整的 ModBus协议帧 ,而这是 易错且低效 的(更长的数据增加了出错的风险,且重发需重发所有帧)。

       ps:因而常规的做法还是将 ModBus协议 所携带的数据进行分包,形成多个ModBus协议包送入无线发送。

  • 同一个 Modbus RTU 网络中不允许出现两台设备地址相同,这样会导致无线信号出现干扰,不能成功接收数据。

断帧方式

由于 ModBus 协议没有限制数据长度。在 ModBus RTU模式中规定,消息发送至少需要以 传输3.5个帧长度所需要的时间 作为停顿间隔开始。在最后一位数据传输完成后,至少需要 传输3.5个帧长度的时间 作为停顿标定消息的结束。

断帧时长的计算

首先我们先了解的概念

波特率:每秒通过信道传输的信息量称为位传输速率,也就是每秒钟传送的二进制位数,波特率 9600 9600 bit/s

在 UART 中,若规定设置起始位1bi t,数据位 8bit,无校验位(若有,奇偶校验也占1bit)结束标志1bit

则一个 UART帧 共计 10bit

在波特率为 9600 的情况下,每秒钟可发送 (9600bit/s)/10bit = 960帧

那么发送一个帧所需要的时间为 1/960 ≈ 1.04ms

按照前面的规定,断帧时间至少需要1.04*3.5 = 3.645ms 

ps:注意不要和下文的超时时长搞混了

完整通讯流程图

注意

  • 从机对于广播帧是不发送应答的
  • 超时处理

图中亦描述了一个现象,即主机发送请求,但发送出错导致从机无应答。

按照之前的协议的设定,主机应该在苦苦等待从机应答...若无应答岂不是主机一直阻塞或通讯阻塞?

作为一个成熟的协议,当然也考虑到了这些问题

采用的方法也很简单,即 超时处理机制。主机超出设定时间未接收到应答包,则会超时重发。

超时时间需要自行计算,计算方法见 西门子中国-Modbus 通讯注意事项及测试(续)

帧格式

正常帧

Addr(从机地址)

 

8bit

CMD(功能码)

 

8bit

Reg(寄存器地址)

 

16bit

 

Num(数据长度)

 

16bit

 

Data(数据)

 

不定长(8bit * n

          n >= 0

CRC(校验位)

 

16bit

可能有人会说,这和上图 ModBus协议常见类型 展示的图片不一样啊,其实还是一样的,只是将数据1和数据2(假设8bit)作为一个16bitNum 数据长度而已。

  • Addr:从机地址,其中0x00一般为广播包,其他地址可自行设定,若从机收到非本从机地址的数据包则会进行丢包处理。(所以从物理层来看,数据还是“广播”的)
  • Cmd:功能码,用于标志该帧功能,常用的有:

功能码

名称

作用

03

读取保持寄存器

在一个或多个保持寄存器中取得当前的二进制值

06

预置单寄存器

把具体二进值装入一个保持寄存器

16

预置多寄存器

把具体的二进制值装入一串连续的保持寄存器

.........

完整的功能码可在附录中查看,为了兼容其他开发者的 ModBus 协议,我们通常采用协议的功能码而不是自定义功能码。

  • Reg:寄存器地址,其值为 待发送/读取数据的首地址
  • Num:寄存器个数
  • Data:数据域
  • CRC:校验码,若 CRC 验证错误则会丢包并请求重发

错误帧

Addr(从机地址)

 

8bit

CMD(功能码)

 

8bit

Error(错误码)

 

8bit

CRC(校验位)

 

16bit

通讯流程

为简化下文表述,约定如下:

Addr

  • 广播地址:0x00
  • 从机1:0x01

Cmd

  • 读多个寄存器:0x03

  • 写单个寄存器: 0x06

  • 写多个寄存器:0x10

  • 读错误:0x83

  • 写单个寄存器错误:0x66

  • 写多个寄存器错误:0x90

Reg

温度数据:0x2000

湿度数据:0x2001

待机时间:0x3000

Error

  • UnCmd: 0x01
  • UnDataAddr:0x02
  • UnDataValue:0x03
  • CrcErr:0x11

主设备读流程

若存在多从机设备

主机接收到错误帧以后会进行相应的处理,常见的处理是重发。

下面是从机收到读请求帧后,CRC 校验失败的错误帧

主设备写流程

Java 中常用的 Modbus库

 

外部链接

ä¼åå¾½æ å¾å½¢

 Modbus组织官网

 

下为ModBus库链接

附录

ModBus 完整CMD功能码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值