Modbus 协议简述


Modbus 主站/从站协议原理

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

单播模式

主节点以特定地址访问某个子节点,子节点接到并处理完请求后,子节点向主节点返回一个报文(一个
'应答')。在这种模式,一个 Modbus 事务处理包含 2 个报文:一个来自主节点的请求,一个来自子节
点的应答。
每个子节点必须有唯一的地址 (1 到 247),这样才能区别于其它节点被独立的寻址。

广播模式

主节点向所有的子节点发送请求。对于主节点广播的请求没有应答返回。广播请求一般用于写命令。
所有设备必须接受广播模式的写功能。地址 0 是专门用于表示广播数据的。

地址规则

0 1-247 248-255
广播 子节点单独地址 保留

Modbus 帧描述

《Modbus 应用协议》定义了简单的协议数据单元(PDU - Protocol Data Unit):

功能码<->数据

发起 Modbus 事务处理的客户端构造 Modbus PDU,然后添加附加的域以构造通信PDU。

地址域<->功能码<->数据<->CRC(或LRC)

  • 如前文所述,合法的子节点地址为十进制 0 – 247。 每个子设备被赋予1 – 247 范围中的地址。
    主节点通过将子节点的地址放到报文的地址域对子节点寻址。当子节点返回应答时,它将自己的地址放到
    应答报文的地址域以让主节点知道哪个子节点在回答。

  • 功能码指明服务器要执行的动作。功能码后面可跟有表示含有请求和响应参数的数据域。

  • 错误检验域是对报文内容执行 "冗余校验" 的计算结果。根据不同的传输模式 (RTU or ASCII) 使用
    两种不同的计算方法。

RTU 传输模式(Remote Terminal Unit)

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

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

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

每字节的bit 流: 1 起始位 8 数据位, 首先发送最低有效位 1 位作为奇偶校验 1 停止位

帧描述

Modbus 报文RTU 帧

由发送设备将Modbus 报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收
新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。

在 RTU 模式,报文帧由时长至少为3.5 个字符时间的空闲间隔区分。在后续的部分,这个时间区间
被称作t3.5。

整个报文帧必须以连续的字符流发送。如果两个字符之间的空闲间隔大于1.5 个字符时间,则报文帧被认为不完整应该被接收节点丢弃。

  • 从 "初始" 态到 “空闲” 态转换需要t3.5 定时超时: 这保证帧间延迟
  • “空闲” 态是没有发送和接收报文要处理的正常状态。
  • 在 RTU 模式, 当没有活动的传输的时间间隔达3.5 个字符长时,通信链路被认为在 “空闲” 态。
  • 当链路空闲时, 在链路上检测到的任何传输的字符被识别为帧起始。 链路变为 "活动" 状态。 然后,
    当链路上没有字符传输的时间间个达到t3.5 后,被识别为帧结束。
  • 检测到帧结束后,完成CRC 计算和检验。然后,分析地址域以确定帧是否发往此设备,如果不是,
    则丢弃此帧。 为了减少接收处理时间,地址域可以在一接到就分析,而不需要等到整个帧结束。这
    样,CRC 计算只需要在帧寻址到该节点 (包括广播帧) 时进行。

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。

MODBUS 事务处理流程

根据处理结果,可以建立两种类型响应:
* 一个正确的MODBUS 响应:响应功能码 = 请求功能码
* 一个MODBUS 异常响应:用来为客户机提供处理过程中与被发现的差错相关的信息;响应功能码 = 请求功能码 + 0x80;提供一个异常码来指示差错原因。

异常码定义

示例:

在这个实例中,客户机对服务器设备寻址请求。功能码(01)用于读输出状态操作。它将请求地址1245(十六进制04A1)的输出状态。值得注意的是,象输出域(0001)号码说明的那样,只读出一个输出。

如果在服务器设备中不存在输出地址,那么服务器将返回异常码(02)的异常响应。这就说明从站的非
法数据地址。


功能码分类

有三类MODBUS 功能码。它们是:公共功能码、用户定义功能码、保留功能码。

公共功能码定义

MODBUS 数据模型有四种,通过不同的功能码来读写这些数据对象。

功能码定义如下:

读线圈寄存器 01H

例如从机地址为11H,线圈寄存器的起始地址为0013H,结束地址为0037H。该次查询总共访问37个线圈寄存器。

响应负载中的各线圈状态与数据内容每位相对应。1代表ON,0代表OFF。若返回的线圈数不为8的倍数,则在最后数据字节未尾使用0代替。

线圈0013H到线圈001AH的状态为CDH,二进制值为11001101,该字节的最高字节为线圈001AH,最低字节为线圈0013H。线圈001AH到线圈0013H的状态分别为ON-ON-OFF-OFF-ON-ON-OFF-ON

最后一个数据字节中,线圈0033H到线圈0037状态为1BH(二进制00011011),线圈0037H是左数第4位,线圈0033H为该字节的最低字节,线圈0037H至线圈0033H的状态分别为ON-ON-OFF-ON-ON,剩余3位使用0填充。

读离散输入寄存器 02H

从机地址为11H。离散输入寄存器的起始地址为00C4H,结束寄存器地址为00D9H。总共访问32个离散输入寄存器。

响应各离散输入寄存器状态,分别对应数据区中的每位值,1 代表ON;0 代表OFF。第一个数据字节的LSB(最低字节)为查询的寻址地址,其他输入口按顺序在该字节中由低字节向高字节排列,直到填充满8位。下一个字节中的8个输入位也是从低字节到高字节排列。若返回的输入位数不是8的倍数,则在最后的数据字节中的剩余位至该字节的最高位使用0填充。


离散输入寄存器00D4H到00D9H的状态为35H (二进制00110101)。输入寄存器00D9H为左数第3位,输入寄存器00D4为最低位,输入寄存器00D9H到00D4H的状态分别为ON-ON-OFF-ON-OFF-ON。00DBH寄存器和00DAH寄存器被0填充。

读保持寄存器 03H

从机地址为11H。保持寄存器的起始地址为006BH,结束地址为006DH。该次查询总共访问多个保持寄存器。


保持寄存器的长度为2个字节。对于单个保持寄存器而言,寄存器高字节数据先被传输,低字节数据后被传输。保持寄存器之间,低地址寄存器先被传输,高地址寄存器后被传输。

输入寄存器 04H

从机地址为11H。输入寄存器的起始地址为0008H,寄存器的结束地址为0009H。本次访问访2个输入寄存器。

输入寄存器长度为2个字节。对于单个输入寄存器而言,寄存器高字节数据先被传输,低字节数据被传输。输入寄存器之间,低地址寄存器先被输,高地址寄存器后被传输。

写单个线圈寄存器 05H

从机地址为11H,线圈寄存器的地址为00ACH。使00ACH线圈处于ON状态,即数据内容为FF00H。

响应

写单个保持寄存器 06H

从机地址为11H。保持寄存器地址为0001H。寄存器内容为0003H。

响应


写多个保持寄存器 10H

从机地址为11H。保持寄存器的其实地址为0001H,寄存器的结束地址为0002H。总共访问2个寄存器。保持寄存器0001H的内容为000AH,保持寄存器0002H的内容为0102H。


响应

写多个线圈寄存器 0FH

从机地址为11H,线圈寄存器的起始地址为0013H,线圈寄存器的结束地址为001CH。总共访问10个寄存器。寄存器内容如下表所示。

传输的第一个字节 CDH对应线圈为0013H到001AH,LSB(最低位)对应线圈0013H,传输第二个字节为 01H,对应的线圈为001BH到001CH,LSB对应线圈001CH,其余未使用位使用0 填充。

响应

  • 分享:
评论
还没有评论
    发表评论 说点什么