Modbus 协议图文详解
1、概论
Modbus是一种串行通信协议,由于其协议简单易用,且没有版权要求,目前已经成为工业领域通信协议的实时标准。ModBus协议是又施耐德电气的前身Modicon公司在1979年提出的。Modbus目前有两个主要版本 ModBus串口,MODBUS TCP/IP。ModBus 串口又有两个变种:Modbus RTU是一种紧凑的,采用二进制表示数据的方式,Modbus ASCII是一种人类可读的,冗长的表示方式。还有一种扩展协议MODBUS PLUS(Modbus+或者MB+),不过此协议是Modicon专有的一种高速令牌传递网络,和Modbus不同,它需要一个专门的协处理器来处理类似HDLC的高速令牌旋转。
下图说明ModBus协议规范和现有协议的关系从图可以看出,Modbus是基于现有OSI 网络模型上的应用协议。
Modbus 协议和 ISO/OSI 模型 具体情况
2、ModBus的应用场景
ModBus协议可以解决工厂不同种类设备的数据采集问题,使得我们可以通过采集的数据随时监控工厂的运行情况。MODBUS 协议允许在各种网络体系结构内进行简单通信,它的常见体系结构图如下。
HMI代表人机界面,PLC是工厂常用的采集设备,工厂中的各类PLC,I/O数据接口,驱动器设备可以通过各类Modbus协议采集它的数据,并且不同Modbus协议网络之间还可以通过网关进行数据交换。
3、Modbus协议内容介绍
3.1 Modbus 网络形式和协议
在介绍Modbus网络之前首先介绍一下Modbus网络上传输的是什么,和其他协议类似,Modbus协议最基本的通信单位是帧,整个Modbus帧又被称之为应用数据单元(ADU),ADU中又包含了协议数据单元(PDU)用于传真正需要传输的数据。
Modbus协议是一个主/从架构的协议。在同一个Modbus网络中同一时刻只有一个节点是主(master)节点,其他使用Modbus协议参与通信的节点是从(slave)节点,从节点的最大编号为247。每一个slave设备都有一个唯一的地址。
在串行和MB+网络中,通讯总是由主节点发起(在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令),子节点在没有收到主节点请求时不会发送数据。各个子节点之间不会直接相互通信。
在同一个时刻,主节点只会发起一个Modbus事务处理。什么是事务处理呢?其实就是一次网络上完整的应答通讯。主要包含两种形式,1 单播模式 , 2 广播模式
所谓单播模式就是主节点给某个指定的节点发送消息(通过ADU中的地址域指定),从节点收到并处理完请求后,从节点向主节点返回一个应答报文,在这种模式下,一个Modbus事务包含两个报文,一个来自主节点的请求,一个来自子节点的应答
所谓广播模式,是主节点向所有的子节点发送请求,当主节点发送的请求报文的地址域值为0时,代表广播请求,所有的从节点都需要接受处理,但不需要向主节点返回报文。
其实在物理层所有设备都会收到所有的请求,但地址域不为0时,从机判断当前为单播模式,只有地址域和自身地址号相同的从机才会响应请求,当地址域为0时,从机判断为广播消息,所有的从机都会执行指令,所有收到指令的设备都会运行,只不过不回应指令。
客户机(主机)和服务器(从机)通信时会出现两种情况,一种是正常,一种是异常。
其中事务处理正常时示意图如下,客户机(主机)向服务器(从机)发送请求,在功能码中填充功能码代号,说明服务器需要执行的动作,在数据码区填充具体的要求,比如读寄存器的地址和数量,通信正常时服务器会在返回的通信帧的功能码区中填充一个操作码,该操作码和功能码的值一样,在通讯帧的数据区填充返回的采样数据。
当出现事务处理异常时,示意图如下,服务器会在返回的通讯帧的功能码中填充一个差错码,该差错码 = 功能码 + 0x80,即将功能码的最高位置1代表出现错误。并在后面的数据段中填充错误码,用来指示本次通信的错误具体内容。
错误检测域是针对通讯链路是否可靠的检测域,通过CRC(循环冗余校验码)等错误校验方式校验通信过程中是否发生了差错。
4、帧详解
Modbus协议的三种形式通讯的帧略有不同,具体如下
MBAP是一个通用的报文头,依赖于可靠的网络层,各域的典型长度如下(以串行链路为例)
各功能域介绍:
4.1、地址域
第一部分是8位是地址域,用于给从机编号,而主机是没有地址的,从机的地址必须是唯一的。Modbus 地址域使用1个字节,寻址空间有 256 个不同地址,但合法的地址是0 – 247。
主节点通过将子节点的地址放到报文的地址域对子节点寻址。当子节点返回应答时, 它将自己的地址放到应答报文的地址域以让主节点知道哪个子节点在回答
4.2、功能码
第二部分8位是功能码,功能码指明服务器要执行的动作。
主机通过在PDU中指定不同的功能码,通知从机(服务器)执行不同的动作, 功能码分为三类:
A、公共功能码:这是Modbus协议组织定义的功能码,被大家一致认可,普通情况下不会改变。
B、用户定义功能码: 有两个用户定义功能码的定义范围,十进制 65 至 72 和十进制 100 至 110,可以用户自行定义使用。
C、保留功能码:这是一些公司对一些历史产品使用的功能码,对公共来说是无效的。
公共功能码的定义如下:
访问形式有单比特访问和16比特访问还有文件记录访问, 这里的线圈可以理解为开关量 0,1
4.3、数据区
介绍数据区之前,先介绍一下Mobbus协议的数据模型,Modbus可访问的数据存储在四个区块或地址范围的其中一个: 线圈状态、离散量输入、保持寄存器和输入寄存器。这里的区块是概念性的定义,在物理层面它们可能作为独立的内存地址存在于给定的系统中,但也可能重叠,这个完全由设备自己管理。
每个区块定义可以包含65,536个元素的地址空间。在PDU的定义中,Modbus定义了每个数据元素的地址,范围从0到65,535。但是我们的物理设备如寄存器、线圈通常从1开始编号从1到n,其中n的最大值为65,536。也就是说,线圈11位于地址10的线圈状态区块中,而保持寄存器34位于从机被定义为保持寄存器的内存部分中的地址33。 实际使用时设备不会直接描述数据在某某号寄存器中,如电压量在第13号保存寄存器中,而是会描述为电压量在地址40001(或者4001,400001等),其中4XXX、4XXXX和4XXXXX的区别取决于设备使用的地址空间。 如果所有65,536个寄存器都在使用中,应该使用4XXXXX符号,因为其允许范围为400,001~465,536。4开头是因为实际使用时地址编码的前缀通常反映数据的类型,一般如下定义数据类型和前缀关系。
4.4、错误检验域
该域是串行链路对报文内容执行 "冗余校验" 的计算结果。根据不同的传输模式 (RTU or ASCII)使用两种不同的计算方法。
4.5、报文示例
请求读离散量输出 20-38 的实例
将输出 27-20 的状态表示为十六进制字节值 CD,或二进制 1100 1101。输出 27 是这个字节的MSB,输出 20 是 LSB。按照惯例,将一个字节内的比特表示为 MSB 位于左侧,LSB 位于右侧。第一字节的输出从左至右为 27 至 20。下一个字节的输出从左到右为 35 至 28。当串行发射比特时,从 LSB 向 MSB 传输: 20 . . .27、28 . . . 35 等等。在最后的数据字节中,将输出状态 38-36 表示为十六进制字节值 05,或二进制 0000 0101。输出38 是左侧第六个比特位置,输出 36 是这个字节的 LSB。用零填充五个剩余高位比特。如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特。设备内部流程如下
4.6 异常代码
5、关于传输
串行传输模式有两种:RTU模式和ASCII模式
Modbus 串行链路 上所有设备的传输模式和串口参数必须相同。所有设备必须实现RTU模式,ASCII模式是选择项,只有配置成相同模式的设备才可以相互正常通信。在其他网络上(如MAP,Modbus Plus)Modbus消息被转换为与串行传输无关的帧。Modbus 使用“大端模式”(big-Endian) 表示地址和数据项。当发送多个字节时,首先发送最高有效位。这是字节层面的,在串口线路中传送每个字节时bit传送模式为,LSB先发送,MSB后发送。
RTU 传输模式
当控制器以RTU模式通信时,消息中每个8bit字节包含两个4bit十六进制字符。这种方式的有点是:在相同波特率下,可以比ASCII方式传送更多数据
相应的串口设置要求
- 1 起始位
- 8 数据位, 首先发送最低有效位
- 1 位作为奇偶校验
- 1 停止位
每个字符或字节均由此顺序发送(从左到右):最低有效位 (LSB) . . . 最高有效位 (MSB)
ASCII 传输模式
当 Modbus 串行链路的设备被配置为使用 ASCII (American Standard Code for Information
Interchange) 模式通信时, 报文中的每个 8 位子节以两个 ASCII 字符发送。当通信链路或者设备
无法符合 RTU 模式的定时管理时使用该模式。
注 : 由于一个子节需要两个字符,此模式比 RTU 效率低。
例 : 子节 0X5B 会被编码为两个字符 : 0x35 和 0x42 ( ASCII 编码 0x35 ="5", 0x42 ="B" )。
相应的串口设置
- 1 起始位
- 7 数据位, 首先发送最低有效位
- 1 位作为奇偶校验
- 1 停止位
和RTU模式一样每个字符或字节均由此顺序发送(从左到右):最低有效位 (LSB) . . . 最高有效位 (MSB)
(ASCII 十六进制 3A )起始,以‘回车-换换行’ (CR LF) 对(ASCII 十六进制 0D 和 0A)结束。