.webp)
Modbus协议详解
Modbus协议详解
简介:
Modbus 协议是一种通信协议,允许设备通过各种类型的介质进行通信,如串行线和以太网。它是由生产可编程逻辑控制器(PLC)的 Modicon 公司于 1979 年开发的,旨在使这些设备能够相互通信。
Modbus 协议提供了一种消息传递结构,用于以主从通信方式在智能设备之间传递消息。主设备 A 发送的 Modbus 消息会触发从设备 B 的回应。Modbus 协议规定了通信内容、信息的封装方式和消息的发送和接收顺序。
Modbus 协议简单而强大,是工业控制系统的热门选择。作为一个开放标准,任何人都可以自由地使用和修改,这使得它在整个行业中得到了广泛应用。
MODBUS对应OSI模型:
Modbus的协议格式
解释:
ADU: 应用数据单元
PDU:协议数据单元
地址域:通信的设备的ID号 1字节
功能码:执行的操作/指令 1字节
数据:发送或者接受的有效数据 252字节
差错校验(CRC):判断数据传输是否正确 2字节
modbus协议通信框图
正确的响应:
错误的响应:
modbus协议执行流程:
modbus数据模型
如果是只需要读数据选择输入寄存器
既要读数据也要写数据选择保持寄存器
Modbus功能码详解
Modbus功能码是Modbus消息帧(报文)的重要组成部分,是Modubs协议中通信事务处理的基础,代表消息将要执行的动作。
功能码概要
简而言之,Modbus功能码占用一个字节,取值范围是1127,之所以127以上不能使用,是因为Modbus规定出现异常时,功能码+0x80(十进制128)代替异常状态,因此129(1+128)255(127+128)的取值代表异常码。
Modbus标准协议中规定了由3类Modbus功能码,分别是:
公共功能码
- 被明确定义的功能码
- 保证唯一性
- 由Modbus协会确认,并提供公开的文档;
- 可进行一致性测试
- 包括协议定义的功能码和保留将来使用的功能码
用户自定义功能码
有两个用户自定义功能码区域,分别是65110;
72和100
用户自定义,不保证唯一性。
保留功能码
保留功能码是因为历史遗留原因,某些公司的传统产品上现行使用的功能码不作为公共使用。
功能码可分为位操作和字操作两类。位操作的最小单位为一位(bit),字操作的最小单位为两个字节。
- 位操作指令:读线圈状态功能码01,读(离散)输入状态功能码02,写单个线圈功能码06和写多个线圈功能码15.
- 字操作指令:读保持寄存器功能码03,读输入寄存器功能码04,写单个保持寄存器功能码06,写多个保持寄存器功能码16.
01(0x01)读取线圈/离散量输出状态
功能说明
读取从设备的线圈或离散量输出的状态,即各DO的ON/OFF状态。消息帧中指定了需读取的线圈起始地址和线圈数目。需要注意的一点是,在Modbus协议规定的PDU中,规定所有线圈或寄存器地址从0开始计算。
查询报文
查询帧的消息里,定义了从设备地址为3,并读取从设备的Modbus地址0001900055(线圈地址0002000056)共计37个状态值。起始线圈地址为0x13(即十进制00019),因为线圈地址从0开始计数。
Modbus协议规定,起始地址由2个字节构成,取值范围为0x00000xFFFF;线圈数量由2个字节构成,取值范围为0x00010x07D0(即十进制1~2000).
ASCII模式中直接按每4个位拆分为对应的字符表示。
响应报文
响应报文的数据字段中,每一个线圈占用1个位(bit),状态被表示为1=ON和0=OFF两种类型。第1个数据字节的LSB(最低有效位)标识查询报文中的起始地址线圈的状态值,其他线圈依次类推,一直到这个字节的MSB(最高有效位)位置,并在后续字节中按照同样的方式(由低到高)排列。
一个字节可以表示8个线圈的状态,如果最后的数据字节中不能填满8个线圈的状态,则由0填充。对应于查询报文中需要读取37个线圈的状态,则共需要5个字节保存状态值。
02(0x02)读取离散量输入值
功能说明
该功能码用于读取从设备的离散输入即DI的ON/OFF状态。消息帧中制定了需读取的离散输入寄存器起始地址和数目,可读取1~2000个连续的离散量输入状态。如果从设备接受主设备的请求则回复功能码02,并返回离散量输入各离散量的当前状态。如果返回的离散输入数量的个数不是8的整数倍,将用0填充最后数据字节的剩余位。
03(0x03)读取保持寄存器值
功能说明
用于读取从设备保持寄存器的内容,不支持广播模式。消息帧中指定了需读取的保持寄存器的起始地址和数目。而保持寄存器中各地址的具体内容和意义,则由设备开发者自行规定。
查询报文
在查询报文中,必须指定保持寄存器的开始地址和需读取的寄存器数量。起始位置由2个字节构成,取值范围为0x00000xFFFF;寄存器数量由2个字节构成,取值范围为0x00010x007D(即十进制1~255),即最多可以连续读取125个寄存器。
有一点特别需要注意,Modbus的保持寄存器和输入寄存器是以字(Word)为基本单位的(1Word=2byte),所以,如果读取保持寄存器地址为40001开始的一个16位(bit)的无符号数,那么返回2个字节(byte),并可以从40002开始读取下一个16位的无符号数。如果需读取寄存器地址40001开始的是一个32位浮点数,则需要返回4个字节,即必须连续读取40001和40002的内容,而且下一个32位浮点数必须从40003开始读取。对于浮点数(或者32位的整数)而言,连续读取的两个寄存器之间存在字节序和大小端的问题,这一点在开发时必须引起注意。
- 感谢你赐予我前进的力量