#申请原创#
@21小跑堂 @21小跑堂 @21小跑堂
很久没法帖子了,今天发一个MODBUS初级分享贴出来,和大家共同学习进步,如果有不对之处希望大家能够多多指正。
言归正传
什么是MODBUS ?
MODBUS 是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。
MODBUS 已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。
我国现在关于MODBUS 的国家标准是
《GBT 19582.1-2008 基于Modbus协议的工业自动化网络规范 第1部分:Modbus应用协议》
《GBT 19582.2-2008 基于Modbus协议的工业自动化网络规范 第2部分:Modbus协议在串行链路上的实现指南》
《GBT 19582.3-2008 基于Modbus协议的工业自动化网络规范 第3部分:Modbus协议在TCP∕IP上的实现指南》
MODBUS 串行链路取决于 TIA/EIA 标准:232-F 和 485-A。
MODBUS TCP/IP 取决于 IETF 标准:RFC793 和 RFC791 有关。
MODBUS 标准分为三部分:
第一部分(“Modbus 协议规范”)描述了 MODBUS 事物处理。
第二部分(“MODBUS 报文传输在串行链路上的实现指南”)提供了一个有助于开发者实现串行链路上的 MODBUS应用层的参考信息。
第三部分(“MODBUS 报文传输在 TCP/IP 上的实现指南”)提供了一个有助于开发者实现 TCP/IP 上的 MODBUS 应用层的参考信息。
接下来我们一部分一部分的介绍
首先说的是协议部分
MODBUS 是 OSI 模型第 7 层上的应用层报文传输协议,它在连接至不同类型总线或网络的设备之间提供客户机/服务器通信。
自从 1979 年出现工业串行链路的事实标准以来,MODBUS 使成千上万的自动化设备能够通信。
目前,继续增加对简单而雅观的 MODBUS 结构支持。互联网组织能够使 TCP/IP 栈上的保留系统端口 502 访问 MODBUS。
MODBUS 是一个请求/应答协议,并且提供功能码规定的服务。MODBUS 功能码是 MODBUS请求/应答 PDU 的元素。本文件的作用是描述 MODBUS 事务处理框架内使用的功能码。
协议描述
MODBUS 协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网络上的 MODBUS 协议映射能够在应用数据单元(ADU)上引入一些附加域。
串行链路上第一个MODBUS 执行的长度约束限制了MODBUS PDU大小(最大RS485ADU=256字节)。
因此, 对串行链路通信来说 ,MODBUS PDU=256-服务器地址(1 字节)-CRC(2 字节)= 253 字节。
从而:RS232 / RS485 ADU = 253 字节+服务器地址(1 byte) + CRC (2 字节) = 256 字节。
TCP MODBUS ADU = 249 字节+ MBAP (7 字节) = 256 字节
MODBUS 以一系列具有不同特征表格上的数据模型为基础。四个基本表格为:
下面就说一下MODBUS的功能码
0x01: 读线圈寄存器
0x02: 读离散输入寄存器
0x03: 读保持寄存器
0x04: 读输入寄存器
0x05: 写单个线圈寄存器
0x06: 写单个保持寄存器
0x0f: 写多个线圈寄存器
0x10: 写多个保持寄存器
01举例:
在一个远程设备中,使用该功能码读取线圈的 1 至 2000 连续状态。
请求 PDU 详细说明了起始地址,即指定的第一个线圈地址和线圈编号。从零开始寻址线圈。因此寻址线圈 1-16 为 0-15。
根据数据域的每个比特将响应报文中的线圈分成为一个线圈。指示状态为 1= ON 和 0= OFF。
第一个数据字节的 LSB(最低有效位)包括在询问中寻址的输出。其它线圈依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。
如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。
发送: 11 01 00 13 00 05 0F 5C
11 设备地址
01 命令号
00 起始寄存器地址高8位
13 起始寄存器地址低8位
00 读取的数据寄存器个数高8位
05 读取的数据寄存器个数低8位
0E CRC校验的低8位
84 CRC校验的高8位
返回: 11 01 05 CD 6B B2 0E 1B 45 E6
11 设备地址
01 命令号01
05 返回字节个数
CD 数据1
6B 数据2
B2 数据3
0E 数据4
1B 数据5
45 CRC低
E6 CRC高
编程可根据下面流程图写程序:
其他功能码类似不再做详细介绍。
当在串行链路通信时,如下图所示
Modbus 寻址空间有 256 个不同地址。地址 0 保留为广播地址。 所有的子节点必须识别广播地址。
Modbus 主节点没有地址, 只有子节点必须有一个地址。 该地址必须在 Modbus 串行总线上唯一。
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。
|
直接上程序!