Modbus协议_概念讲解

  这里分享一下在嵌入式设备与PLC通讯中的一种很常见的通讯协议:Modbus通讯

一、基本概念

  Modbus协议 是一个请求/应答协议,发起请求的为Master(client),响应请求的为Slave(server);Modbus协议包括ASCII、RTU、TCP三种报文类型,并没有规定物理层。

  标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。


  • Master端发出读数据请求消息,Slave端接收到正确消息后,就发送对应数据到Master端以响应请求;
  • Master端发出写数据请求消息,Slave端接收到正确消息后,就修改Slave端的数据;

先发请求,再接收响应,从而实现 主机 对 从机 读/写操作。

二、报文格式_通用部分

  • (ADU)报文,指的是一串完整的指令数据;一个报文就是一帧数据,一个数据帧就一个报文
  • (MBAP)报文头,即报文的一部分,用于识别。当然也有些是部分数据在报文尾部,例如CRC数据校验。
  • (PDU)协议数据单元,这部分就是通信中的数据部分了。

举例如下:

  由于报文类型的不同,报文之间也存在一些差异。先讲解通用的 功能码 & 错误代码 部分。

2.1 Modbus部分功能码

功能码(十六进制) 中文名称 位操作/字节操作 操作数量 错误功能码(&0x80)
01 读线圈状态 位操作 单个或多个 0x81
02 读离散状态 位操作 单个或多个 0x82
03 读保持寄存器 字节操作 单个或多个 0x83
04 读输入寄存器 字节操作 单个或多个 0x84
05 写单个线圈 位操作 单个 0x85
06 写单个保持寄存器 字节操作 单个 0x86
0F 写多个线圈 位操作 多个 0x8F
10 写多个保持寄存器 字节操作 多个 0x90

  Modbus协议规定,从机当执行对应功能码处理时发生错误,响应主机时需要将 功能码 & 0x80 将其返回。

2.2 错误代码表

代码 名称 含义
01 非法功能 对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作,可能是因为功能码仅适用于新设备而被选单元中不可实现同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:它是未配置的,且要求返回寄存器值。
02 非法数据地址 对于服务器(或从站)来说,询问中接收的数据地址是不可允许的地址,特别是参考号和传输长度的组合是无效的。对于带有100个寄存器的控制器来说,偏移量96和长度4的请求会成功,而偏移量96和长度5的请求将产生异常码02。
03 非法数据值 对于服务器(或从站)来说,询问中包括的值是不可允许的值。该值指示了组合请求剩余结构中的故障。例如:隐含长度是不正确的。modbus协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。
04 从站设备故障 当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
05 确认 与编程命令一起使用,服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。
07 从属设备忙 与编程命令一起使用,服务器(或从站)正在处理长持续时间的程序命令,当服务器(或从站)空闲时,客户机(或主站)应该稍后重新传输报文。
08 存储奇偶性差错 与功能码20和21以及参考类型6一起使用,指示扩展文件区不能通过一致性校验。服务器(或从站)设备读取记录文件,但在存储器中发现一个奇偶校验错误。客户机(或主机)可重新发送请求,但可以在服务器(或从站)设备上要求服务。
0A 不可用网关路径 与网关一起使用,指示网关不能为处理请求分配输入端口值输出端口的内部通信路径,通常意味着网关是错误配置的或过载的。
0B 网关目标设备响应失败 与网关一起使用,指示没有从目标设备中获得响应,通常意味着设备未在网络中。
## 2.3 Modbus 寄存器地址分配
寄存器信息地址(PLC 地址) 适用功能码(十六进制) 寄存器种类
—- —-
00001-09999 01 05 15 线圈状态
10001-19999 02 (开关)输入状态
30001-39999 04 输入寄存器
40001-49999 03 06 16 保持寄存器
## 2.4 小总结(心得)
  一般情况下,只需要看一下返回的功能码就行了,错误代码可以不用看。Modbus通讯发生错误,往往出现的情况如下:
1. Modbus主机(PLC)读取有问题,例如读的地址写错,读的数据长度写错
2. Modbus从机压根就没写该 功能码 0r 地址 对应的处理,当主机对其操作自然报错。
3. 并不是符合Modbus协议规范的报文就一定通信正确,只能说是通讯成功,因为它返回给你一条报错指令。通讯无响应,说明是主机本身发的数据就有问题;通信有响应(可能返回错误报文),说明该地址不可用,主机读歪了或者从机压根没写该功能处理。

三、各报文格式_详细解析

  每个报文都与其他报文格式有一定区分。在Modbus从机的角度看,讲解一下他们之间的类似之处。

  • 三者功能码是通用的
  • RTU 和 TCP的报文十分类似。TCP由于是可靠的协议,且通过IP连接,相比RTU就少了 设备ID & CRC数据校验。数据单元部分是完全一样的。
  • RTU & ASCII 都是通过串口通讯的,因此都是需要 定时器。但是定时器具体用法不相同。

Ps:
ASCII模式,国内基本没用到。常用的是 RTU & TCP 模式。

3.1 RTU模式

  Modbus RTU协议中没有明显的开始符和结束符,而是通过帧与帧之间的间隔时间来判断的。如果在指定的时间内,没有接收到新的字符数据,那么就认为新的帧接收完毕。接下来就是处理数据。Modbus通过时间来判断帧接收完成,自然需要 MCU 的定时器配合(3.5T)。
| 设备地址 | 功能代码 | 数据 | CRC校验 | 结束符(实际报文可没有这个!)
| — | —- | — | —- | —
| 1个字节 | 1个字节 | n个字节 | 2个字节 | T1-T2-T3-T4

  • 地址码:每个从机都必须有唯一的地址码ID(从1到247,0是广播地址),并且只有符合地址码的从机才能响应回送。当从机回送信息时,相应的地址码表明该信息来自于何处。
  • 功能码:主机发送的功能码告诉从机执行什么任务。ModBus通讯规约定义功能号为1到127。表2-1列出部分常用功能码,以备查询。
  • 数据区:数据区包含需要从机执行什么动作或由从机采集的返送信息。应答包中,数据包括了数据字节长度+数据值,请求包中数据只包含数据值。
  • 校验码:主机或从机可用校验码进行判别接收信息是否出错。

  • 从Modbus主机角度上看
    • 使用RTU模式,消息发送至少要以3.5个字符时间的停顿间隔开始(如上图的T1-T2-T3-T4所示)。传输的第一个域是设备地址。可以使用的传输字符是十六进制的0…9,A…F。网络设备不断侦测网络总线,包括停顿间隔时间内。当第一个域(地址域)接收到,每个设备都进行解码以判断是否发往自己的。在最后一个传输字符之后,一个至少3.5个字符时间的停顿标定了消息的结束。一个新的消息可在此停顿后开始。
    • 一旦连续发送间隔 小于3.5T,就会对从机数据接收造成 数据黏合
  • 从Modbus从机角度上看
    • 整个消息帧必须作为一连续的流传输,如果在帧完成之前有超过1.5个字符时间的停顿时间则为非法帧;如果一个新消息在小于3.5个字符时间内接着前个消息开始,接收的设备将认为它是前一消息的延续,这将导致一个错误,因为在最后的CRC域的值不可能是正确的。即帧之间的间隔必须大于3.5T,帧内字符的间隔必须小于1.5T。实际应用中1.5T一般不处理,只采用3.5T进行处理(FreeModBus开源代码就是这样)。
    • FreeModbus库,采用的是3.5T作为判断。只要是超过3.5T,就视为两个数据帧处理。当然,如果主机发送数据异常,让 某条报文中间字符发送相隔时间超过3.5T,那么就会造成 1条正确报文被分割成2条报文,造成 数据裂开。
    • 数据裂开一般不会出现。采用FreeModbus库时,正常情况下,高波特率会对3.5T的值进行限制。如果解开该限制,导致3.5T实际值太小(高波特率转换计算出来),这时候主机的字符发送间隔慢一点,从机将无法识别到正确的报文(数据被分裂)。

3.2 ASCII模式

  除了数据域为ASCII码,其它域可以使用的传输字符是十六进制的0…9,A…F。网络上的设备不断侦测“:”字符,当有一个冒号接收到时,每个设备都解码下个域(地址域)来判断是否发给自己的。消息中字符间发送的时间间隔(MCU 的定时器)最长不能超过1秒,否则接收的设备将认为传输错误。

起始位 设备地址 功能代码 数据 LRC校验 结束符
2个字符 2个字符 n个字符 2个字符 2个字符

  使用ASCII模式,消息以冒号(:)字符(ASCII码 3AH)开始,以回车换行符结束(ASCII码 0DH,0AH)

3.3 TCP/IP模式

  与MODBUS RTU相比,少了校验域和地址码,其中地址码被放到MBAP报文头里面了(即 00 00),没有校验域是因为TCP本身就有校验所以省略了。

报文头MBAP,长度为7字节,组成如下:

  • 事务处理标识 :可以理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文(主机要注意的点,从机不对该数据进行识别处理)。
  • 协议标识符 :00 00表示ModbusTCP协议。
  • 长度 :表示接下来的数据长度,单位为字节。
  • 单元标识符 :可以理解为设备地址。
事务处理标识 协议标识 长度 单元标识符 功能代码 数据
2字节 2字节 2字节 1字节 1字节 n字节

四、调试工具

  • 如果你做的是Modbus Master,可以使用modbus slave工具模拟从设备来调试,该工具下载地址:Modbus Slave
  • 如果你做的是Modbus Slave,可以使用modbus poll工具模拟主设备来调试,该工具下载地址:Modbus Poll

以上两个工具的使用方法,可以参考此博客:Modbus测试工具ModbusPoll与Modbus Slave使用方法

-------------本文结束感谢您的阅读-------------