本章是整理知识内容,为强化知识长期更新。
以下部分超链接需要科学上网。
ModBus
modbus是一种通讯协议,是Modicon公司1979年为使用可编程逻辑控制器(PLC)通讯而发表。Modbus是工业领域通讯协议的业界标准之一,目前也我国国家标准工业通讯协议中的重要成员之一。
介绍
Modbus采用主从(Master-Salve)通信模式,仅有主设备(Master)能对传输进行初始化,从设备(Slave)根据主设备的请求进行应答。 __在主从关系中,通信总是成对发生。一个设备必须发起请求,然后等待响应 - 并且发起设备(主设备)负责发起每次交互。 通常,主设备是人机界面(HMI)或监控和数据采集(SCADA)系统,从设备是传感器、可编程逻辑控制器(PLC)或可编程自动化控制器(PAC)。 这些请求和响应的内容以及发送这些消息的网络层由协议的不同层来定义__。
- 在串行链路的主从通信中,Modbus主设备可以连接一个或N(最大为247)个从设备,主从设备之间的通信包括单播模式和广播模式。
- 在广播模式中,Modbus主设备可同时向多个从设备发送请求(设备地址0用于广播模式),从设备对广播请求不进行响应。
- 在单播模式中,主设备发送请求至某个特定的从设备(每个Modbus从设备具有唯一地址),请求的消息帧中会包含功能代码和数据,比如功能代码“01”用来读取离散量线圈的状态。从设备接到请求后,进行应答并把消息反馈主设备。
- __主设备不发送数据,从数据是不会自己发出数据的;即必须是主设备发出查询请求才能建立通讯。 __
消息帧校验方式
- ASCII消息帧:
LRC(纵向冗长检测)
- CRCi消息帧:
CRC(循环冗长检测)
- ASCII消息帧:
ModBus是OSI模型第七层上即__应用层__报文传输协议。
ModBus支持多工业设备、包括
PLC
、DSC
、变频器
、智能仪表等都在应用。ModBus支持多种电气接口,如
RS-232
、RS-485
等,还可以在各种介质上传送,如双绞线、光纤、无线。ModBus协议完全免费;
帧格式
简单,紧凑。ModBus对线缆的要求、长度、波特率,终端电阻,接地,连接器,通信状态的LED指示,都有电气标准。
ModBus数据可以分为两大类,分别为Coil和Register,每一种数据,根据读写方式的不同,又可细分为两种(只读,读写)。
- Coli是位(bit)变量。
- Register是整型(word ,即 16 - bit )。
Primary tabels | Object Type | Type Of | comments |
---|---|---|---|
Discretes Input 离线输入量 | Single bit | 只读 | IO系统提供这种类型的数据 |
Coils 线圈 | Single bit | 只写 | 通用应用程序改变这种类型的数据 |
Input Registers 输入寄存器 | 16-bit word | 只读 | IO系统提供这种类型的数据 |
Holding Registers 保持寄存器 | 16-bit word | 只写 | 通用应用程序改变这种类型的数据 |
关键字概述
-
- 开放式系统互联网通讯参考模型,也就是常说的OSI七层通讯模型。
-
- 这里的PLC是指:
可编程逻辑控制器
,一种具有微处理器的数位逻辑控制器,用户自动化控制。关于可编程逻辑控制器
- 这里的PLC是指:
-
- 这里的DSC是之:
数字信号控制器
,是单片机
和数字信号处理
的集合(DSPs)的集合。
- 这里的DSC是之:
-
- RS-232是美国EIA定制的串行数据通讯的接口。
RS-485
- 现在叫EIA-485,电器特性规定双线、双半工、平衡传输线多点通讯的标准;实现此标准的数字通讯网可以在有电子噪声的环境下经行长距离有效的通信,在线性多点总线的配置下,可以在一个网络上有多个接收器,因此适用在工业环境中。
帧格式
- ModBus是请求/应答协议,并且提供功能码规定服务
- ModBus ASCII
- ModBus RTU
- ModBus TCP/IP
- RTU是必须支持的,其余可选,ModBus RTU帧最大字节256字节。
- ModBus是请求/应答协议,并且提供功能码规定服务
ModBus RTU解析
( Remote Terminal Unit )
- MODBUS RTU消息是一个简单的16位CRC(循环冗余校验和)。这些信息的简单性在于确保可靠性。由于这种简单性,基本的16位MODBUS RTU寄存器结构可用于打包浮点,表格,ASCII文本,队列和其他无关数据。
- RTU软件实现上特质
- 默认的通讯
波特率
9600bps,8位数据位,偶校验,一位停止。 - 奇校验和无校验是可选的,系统必须支持默认的配置,并且对配置错误有异常管理。
- 默认的通讯
- Modbus 的 RTU 模式规定不同数据帧之间的间隔是3.5个字节通信时间以上。如果在一帧数据完成之前有超过3.5个
字节时间的停顿
,接收设备将刷新当前的消息并假定下一个字节是一个新的数据帧的开始。同样的,如果一个新消息在小于3.5个字节时间内接着前边一个数据开始,接收设备将会认为它是前一帧数据的延续。这将会导致一个错误,因此大家看 RTU 数据帧最后还有 16bit 的 CRC 校验。起始位
和结束符
:一个数据帧,前后都至少有3.5个字节的时间间隔,起始位和结束符实际上没有任何数据,T1-T2-T3-T4 代表的是时间间隔3.5个字节以上的时间,而真正有意义的第一个字节是设备地址。设备地址
:在多机通信的时候,数据那么多,依靠这个设备地址字节。每个设备都有一个自己的地址,当设备接收到一帧数据后,程序首先对设备地址字节进行判断比较,如果与自己的地址不同,则对这帧数据直接不予理会,如果与自己的地址相同,就要对这帧数据进行解析,按照之后的功能码执行相应的功能。如果地址是 0x00,则认为是一个广播命令,就是所有的从机设备都要执行的指令。功能代码
:在第二个字节功能代码字节中,Modbus 规定了部分功能代码,此外也保留了一部分功能代码作为备用或者用户自定义,下面有一个ModBus功能码。数据
:跟在功能码后面的是n个8Bit数据。这个n值有多少,取决功能代码决定,不同的功能码后面的数据数据也不同。CRC校验
:CRC校验是一种数据算法,是用来校验数据对错的。__CRC校验函数吧一帧数据除最后两个字节外,前面所有的字节进行特定的算法计算。计算完后生成一个16Bit的数据,作为CRC校验码,添加在一帧数据的最后。接收方接收到数据后,同样会把前边的字节进行 CRC 计算,计算完了再和发过来的 16bit 的 CRC 数据进行比较__,如果相同则认为数据正常,没有出错,如果比较不相同,则说明数据在传输中发生了错误,这帧数据将被丢弃,就像没收到一样,而发送方会在得不到回应后做相应的处理错误处理。
- RTU 模式字节分布
- 1个起始位、8个数据位,最小有效位先发送、1个奇偶校验位(如果无校验则没有这一位)、1位停止位(有校验位时)或者2个停止位(无校验位时)。
通信帧被称为ADU(Application Data Unit), 其中功能代码和数据段组合称为协议数据单元PDU(Protocol Data Unit)
- 上图是一个标准的RTU帧。
- 起始位 :
T1-T2-T3-T4
- 地址域(设备地址) :
8Bit
- 功能代码:
8Bit
- 数据:
n个8Bit
- 差错校验(CRC校验):
16Bit
- 结束符:
T1-T2-T3-T4
- 起始位 :
START | ADDR | CS | DATA | CRC | END |
---|---|---|---|---|---|
初始结构 | 地址码 | 功能码 | 数据区 | 错误校验 | 结束结构 |
延时(相当于4个字节时间) | 1字节 | 1字节 | N字节 | 2字节 | 延时(相当于4个字节时间) |
- 在软件实现上,采用默认的RTU帧结构。
- 发送设备将 Modbus报文构造为带有已知起始和结束标记的帧。这使设备可以在报文的开始接收新帧,并且知道何时报文结束。不完整的报文必须能够被检测到而错误标志必须作为结果被设置。在RTU模式,报文帧由时长至少为 3.5 个字符时间的空闲间隔。
- ModBus采用的是大端模式,就是比如一个16位的电流有效值,是先发送高字节,在发送低字节,但在CRC校验域切记是先发送低字节,在发送高字节,每个字节是先发送低位在发送高位,如下图所示
字节停顿时间
串口发送 一帧数据的停顿时间如何计算?
- 波特率:发送二进制数据位的速率,习惯上用 baud 表示,即我们发送一位二进制数据的持续时间=1/baud
- 如果波特率为9600,发送一个位需要的时间为1/9600s=0.0001042s=0.1042ms,这里按数据位为8位,停止位为2位, 加起来就是10位,10个位发送所需的时间为:0.104210ms = 1.042ms,如果我要发送10个字节的数据,那发送这10个字节数据给接收方需要 的时间为:101.042ms = 10.42ms,这是算实际的发送10个字节的数据所需要的时间。我们在接收方接收数据时可以 把时间再加宽一些,让它有一点余量。让接收方能稳定的把数据从发送方接手过来,可以加个5ms,或更宽一点10ms, 加上发送10个字节所花的时间,就是15ms或20ms。 其他波特率依此类推。
ModBus功能码
功能码 | 名称 | 作用 |
---|---|---|
01 | 读取线圈状态 | 取得一组逻辑线圈的当前状态(ON/OFF) |
02 | 读取输入状态 | 取得一组开关输入的当前状态(ON/OFF) |
03 | 读取保持寄存器 | 在一个或多个保持寄存器中取得当前的二进制值 |
04 | 读取输入寄存器 | 在一个或多个输入寄存器中取得当前的二进制值 |
05 | 强置单线圈 | 强置一个逻辑线圈的通断状态 |
06 | 预置单寄存器 | 把具体二进值装入一个保持寄存器 |
07 | 读取异常状态 | 取得 8 个内部线圈的通断状态,这 8 个线圈的地址由 控制器决定,用户逻辑可以将这些线圈定义,以说明 从机状态,短报文适宜于迅速读取状态 |
08 | 回送诊断校验 | 把诊断校验报文送从机,以对通信处理进行评鉴 |
09 | 编程(只用于 484) | 使主机模拟编程器作用,修改 PC 从机逻辑 |
10 | 控询(只用于 484) | 可使主机与一台正在执行长程序任务从机通信,探询 该从机是否已完成其操作任务,仅在含有功能码 9 的报文发送后,本功能码才发送 |
11 | 读取事件计数 | 可使主机发出单询问,并随即判定操作是否成功,尤 其是该命令或其它应答产生通信错误时 |
12 | 读取通信事件记录 | 可使主机检索每台从机的 ModBus 事务处理通信事件 记录。如果某项事务处理完成,记录会给出有关错误 |
13 | 编程(184/384 484 584 ) | 可使主机模拟编程器功能修改 PC 从机逻辑 |
14 | 探询(184/384 484 584) | 可使主机与正在执行任务的从机通信,定期控询该从 机是否已完成其程序操作,仅在含有功能 13 的报文 发送后,本功能码才得发送 |
15 | 强置多线圈 | 强置一串连续逻辑线圈的通断 |
16 | 预置多寄存器 | 把具体的二进制值装入一串连续的保持寄存器 |
17 | 报告从机标识 | 可使主机判断编址从机的类型及该从机运行指示灯 的状态 |
18 | 884 和 MICRO 84 | 可使主机模拟编程功能,修改 PC 状态逻辑 |
19 | 重置通信链路 | 发生非可修改错误后,是从机复位于已知状态,可重 置顺序字节 |
20 | 读取通用参数(584L) | 显示扩展存储器文件中的数据信息 |
21 | 写入通用参数(584L) | 把通用参数写入扩展存储文件,或修改 |
22~64 | 保留作扩展功能备用 | |
65~72 | 保留以备用户功能所用 | 留作用户功能的扩展编码 |
73~119 | 非法功能 | |
120~127 | 保留 | 留作内部作用 |
128~255 | 保留 | 用于异常应答 |
小试牛刀
文档看了,用模拟器来测试下。
首先需要模拟一个COM串口。不然怎么测试呢。自行百度VSPD。
然后在测试下上图中COM1、COM2
虚拟串口。
串口数据测试互通之后就可以使用Modbus测试工具来测试了。
工具清单
- Modbus poll
- Modbus savel
下载后自行寻找注册码,开始准备测试。
这里是4组测试。ModbusSlave模拟4个设备的数据。ModbusPoll中去分别获取四个设备的数据。测试依据参考Modbus数据类型,读写情况。这里简单的测试4种读。
这里只做演示,具体使用网上有很多教程解释了。这俩软件挺简单的。
工具下载地址
参考文献
串行口,spi,RS232,RS485,RJ45口以及Modbus协议,这些的区别和共同点是什么?
Modbus: 1. Java使用Modbus读取Slave端数据(TCP)