跳到主要内容
版本:1.10.19_build_7.5.9.58

MODBUS协议

Modbus是一个工业上常用的通讯协议。此协议定义了一个控制器能认识使用的消息结构;描述了一个控制器请求访问其它设备的过程,如何回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。


1、Modbus协议描述

Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上的Modbus协议映射能够在应用数据单元(ADU)上引入一些附加域。

启动Modbus事务处理的客户机(主机)创建Modbus应用数据单元。功能码向服务器(从机)指示将执行哪种操作。Modbus协议规范了主机的请求格式,如上图所示。

一个Modbus ADU最大长度为256字节。

1字节地址域,指示从机地址。可以编码0-255共256个地址。Modbus主机没有地址,从机必须有唯一的地址。地址0为广播模式,即主机向所有从机发布消息。地址1-247为从机单独地址,248-255为保留地址。一对一通信时,通常将从机地址定义为1。

1字节功能码,编码Modbus数据单元的功能码域。有效的功能码范围是十进制1-255(128-255 为异常响应保留)。当从主机向从机设备发送消息时,功能码通知从机执行哪种操作。有些功能码具有子功能码,来实现多项操作。

若干位含有请求和响应参数的数据域,从机使用这些数据执行功能码定义的操作。这个域还包括离散项目和寄存器地址、处理的项目数量以及域中的实际数据字节数。在某种请求中,数据域可以是不存在的(0长度),在此情况下服务器不需要任何附加信息。功能码仅说明操作。

2字节错误检验,对报文内容执行"冗余校验" 的计算结果,具体实现在后文介绍。

Modbus串行链路协议是一个主-从协议。在同一时刻,只有一个主机连接于总线,一个或多个从机(最大编号为247 )连接于同一个串行总线。Modbus通信总是由主机发起。从机在没有收到来自主机的请求时,从不会发送数据。从机之间从不会互相通信。主机在同一时刻只会发起一个Modbus事务处理。

如果在一个正确接收的Modbus ADU 中,不出现与请求Modbus 功能有关的差错,那么从机至主机的响应数据域包括请求数据。如果出现与请求Modbus 功能有关的差错,那么域包括一个异常码,从机应用能够使用这个域确定下一个执行的操作。

当从机对主机响应时,它使用功能码域来指示正常(无差错)响应或者出现某种差错(称为异常响应)。对于一个正常响应来说,从机仅对原始功能码响应。下图显示了事务处理正常和异常的过程。

对于异常响应,从机返回一个与原始功能码等同的码,设置该原始功能码的最高有效位为逻辑1。

Modbus 协议定义了三种PDU。它们是:

Modbus请求PDU,mb_req_pdu;

Modbus响应PDU,mb_rsp_pdu;

Modbus异常响应PDU,mb_excep_rsp_pdu。

2、Modbus数据模型

Modbus以4种具有不同特征表格上的数据模型为基础。

以下主要介绍写线圈和写保持寄存器的方法。

3、功能码

3.1 功能码定义

写多个线圈:功能码0x0F

写多个寄存器:功能码0x10

3.2 写多个寄存器(0x10)

表 2    主机请求PDU

表 3   从机响应

N为寄存器数量。

如果出现错误,则从机返回1字节差错码0x90,1字节异常码01或02或03或04

例如,主机发送:01 10 00 0B 00 01 02 00 01 66 EB

01 表示向地址为1的从机写数据,10是功能码,00 0B是起始地址,00 01表示1个寄存器,02表示写入的数据长度为2个字节,00 01是写入的数据内容,66 EB是主机自动生成的校验位。

因此这条信息表示:将“00 01”写入1号从机00 0B开始的地址处。

3.3 写多个线圈(0x0F)

表 4   主机请求PDU

输出字节数N=输出线圈数量/8,如果余数不等于0,则加1取整。

表 5   从机响应

逻辑1对应开关量输出为“ON”,逻辑0对应开关量输出为“OFF”。

如果写入线圈个数不是8的倍数,最后字节中未被使用的比特会用0填充。

如果出现错误,则从机返回1字节差错码0x8F,1字节异常码01或02或03或04。

例如,主机发送:01 0F 00 00 00 0A 02 A0 01 5C F8

01 表示向地址为1的从机写线圈,0F是功能码,00 00是起始地址,00 0A表示写10个线圈,02表示写入的数据占据2个字节,A0 01是写入的数据内容,5C F8是主机自动生成的校验位。

A0 01写成二进制形式是:1010 0000 0000 0001,其中1010 0000是实际数据的第7位——第0位,0000 0001中的最后两位01是实际数据的第9位和第8位,前面6位是补0。因此,实际传输的10个线圈量从低位到高位是:0000 0101 10。

因此这条信息表示:将0000 0101 10这10个线圈写入1号从机00 00开始的地址处。

4、RTU传输模式

设备使用RTU模式。

当设备使用RTU (Remote Terminal Unit) 模式在Modbus 串行链路通信,报文中每个8位字节含有两个4 位十六进制字符。这种模式的主要优点是较高的数据密度,在相同的波特率下比ASCII 模式有更高的吞吐率。每个报文必须以连续的字符流传送。

RTU 模式每个字节( 11 位) 的格式为 :

编码系统: 8位二进制

报文中每个8 位字节含有两个4 位十六进制字符(0–9, A–F)

Bits per Byte: 1 起始位

8 数据位, 首先发送最低有效位

1 位作为奇偶校验

1 停止位

为了保证与其它产品的最大兼容性,建议不使用奇偶校验校验模式。默认校验模式必须为偶校验。使用无校验时要求2个停止位。

传送时,每个字符或字节均由此顺序发送(从左到右):

Modbus报文RTU帧

由发送设备将Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。在 RTU 模式,报文帧由时长至少为3.5个字符时间的空闲间隔区分。在后续的部分,这个时间区间被称作t3.5。

5、CRC校验

在RTU模式包含一个对全部报文内容执行的,基于循环冗余校验(CRC - Cyclical Redundancy Checking)算法的错误检验域。CRC域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。

CRC包含由两个8位字节组成的一个16位值。

CRC域作为报文的最后的域附加在报文之后。计算后,首先附加低字节,然后是高字节。CRC高字节为报文发送的最后一个子节。

附加在报文后面的CRC的值由发送设备计算。接收设备在接收报文时重新计算CRC的值,并将计算结果于实际接收到的CRC值相比较。如果两个值不相等,则为错误。

CRC的计算, 开始对一个16位寄存器全部预装1。然后将报文中的连续的8 位字节对其进行后续的计算。只有字符中的8个数据位参与生成CRC的运算,起始位,停止位和校验位不参与CRC计算。

CRC 的生成过程中, 每个 8位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动(Shift) 1位,而最高有效位(MSB)位置充零。然后提取并检查LSB:如果LSB 为1, 则寄存器中的值与一个固定的预置值异或;如果LSB 为 0, 则不进行异或操作。

这个过程将重复直到执行完8 次移位。完成最后一次(第8 次)移位及相关操作后,下一个8位字节与寄存器的当前值异或,然后又同上面描述过的一样重复8 次。当所有报文中字节都运算之后得到的寄存器中的最终值,就是CRC。