最后更新:2022-07-23 14:32:52 手机定位技术交流文章
Modbus通信协议细节
Modbus RTU通信协议在数据通信中采用主机响应方法实现.只能由主机(PC,(例如HMI)只从机器地址开始请求,从机器(终端设备)响应主机的请求,即半双工通讯。协议只允许主机启动请求,从机进行被动响应,因此, 机器不主动占用通信线,造成数据冲突.
与Modbus RTU协议类似,主服务器响应协议也用于Siemens PPI,通常用于计量器的DL/T645-2007协议。
信息在非同步模式下传输,使用16级通信,信息帧格式:
地址码 |
功能码 |
数据区 |
CRC校验码 |
1字节 |
1字节 |
N字节 |
2字节 |
地址代码是每个通信信息帧的第一个字母,通常支持1到247,有些设备也支持接收从主机发送数据的0地址。每个主机必须有一个地址在总线上,只有与主机发送的地址代码相符的主机才能响应返回数据。
函数代码是每个通信信息框中的第二个字符,主机发送函数代码,告诉机器设备应该执行哪些操作。
常见的八种功能码:
功能码 |
定义 |
操作 |
01H |
读取线圈 |
读一个或多个连续循环状态 |
05H |
写单个线圈 |
在指定的位置运行循环状态 |
0FH |
写多个线圈 |
多个连续循环状态的操作 |
02H |
读取离散量输入 |
读一个或多个连续离散输入状态 |
04H |
读取输入寄存器 |
读一个或多个连续输入登记数据 |
03H |
读保持寄存器 |
读一个或多个存储登记数据 |
06H |
写单个保持寄存器 |
将两个16位数字的数据写入相应的位置 |
10H |
写多个保持寄存器 |
将4*N16英寸的数据写入N连续存储记录中 |
数据区域根据函数代码和数据方向变化,这些数据可以是不同的组合,例如“第一地址+接收机数”,“第一地址+操作数据”,“第一地址+操作数据数+数据长度+数据”,在“功能代码分析”中,详细说明了不同功能代码的数据领域。
Modbus RTU协议在需要数据传输的稳定性和精度的工业中被广泛应用,因此,CRC校正保证数据传输的准确性和完整性。
地址和CRC校正错误不会从机器接收数据反馈,其他错误将返回错误代码给主机。 数据帧的第二位元加上0X80表示请求错误发生(例如非法函数代码、非法数据值等)。 错误数据帧如下:
地址码 |
功能码 |
错误码 |
CRC校验码 |
1字节 |
1字节 |
1字节 |
2字节 |
常见错误码如下:
值 |
名称 |
说明 |
01H |
非法的功能码 |
不支持此函数代码操作登记 |
02H |
非法的寄存器地址 |
禁止访问设备存储设备 |
03H |
非法的数据值 |
写入不支持的参数值 |
04H |
从机故障 |
设备工作异常 |
当通信命令从主机发送时,从主机接收与主机发送的地址代码相符的通信命令,如果CRC检查正确,则执行相应的操作,然后将执行结果(数据)返回到主机。返回信息包含地址代码、函数代码、执行数据和CRC校正代码。如果地址不匹配,或RCC检查错误,它不会返回任何信息。
例如: 主机从主机地址读取01H, 初始循环地址为00H, 主机发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
01 |
|
起始线圈地址 |
高字节 |
00 |
低字节 |
00 |
|
线圈数量 |
高字节 |
00 |
低字节 |
01 |
|
CRC校验 |
低字节 |
FD |
高字节 |
CA |
|
如果机器注册表00H的线圈关闭,机器返回:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
01 |
|
字节数 |
01 |
|
线圈状态 |
01 |
|
CRC校验码 |
低字节 |
90 |
高字节 |
48 |
|
例如: 主机控制来自主机地址01H的四个环态,启动环态地址00H,主机发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
0F |
|
起始线圈地址 |
高字节 |
00 |
低字节 |
00 |
|
线圈数量 |
高字节 |
00 |
低字节 |
04 |
|
写入字节数 |
01 |
|
控制方式 |
00(全部停电),0F(全部关闭) |
|
CRC校验 |
低字节 |
XX |
高字节 |
XX |
|
函数代码0FH操作从机器返回:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
0F |
|
起始线圈地址 |
高字节 |
00 |
低字节 |
00 |
|
线圈数量 |
高字节 |
00 |
低字节 |
04 |
|
CRC校验 |
低字节 |
54 |
高字节 |
08 |
|
功能代码02H:读离散输入
例如: 主机从主机地址01H读取,从离散地址00H的4个输入状态开始,主机发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
02 |
|
起始离散量地址 |
高字节 |
00 |
低字节 |
00 |
|
读取数量 |
高字节 |
00 |
低字节 |
04 |
|
CRC校验 |
低字节 |
79 |
高字节 |
C9 |
|
如果从初始地址00H开始的所有4个离散输入被检测到输入时,机器返回:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
02 |
|
字节数 |
01 |
|
离散输入状态 |
0F |
|
CRC校验码 |
低字节 |
E1 |
高字节 |
8C |
|
例如: 主机从主机地址01H、初始主机地址02H中读取,输入主机的数据,主机发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
04 |
|
起始寄存器地址 |
高字节 |
00 |
低字节 |
02 |
|
寄存器数量 |
高字节 |
00 |
低字节 |
01 |
|
CRC校验 |
低字节 |
90 |
高字节 |
0A |
|
如果机器向02H登记器的输入为3344H,则机器的返回为:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
04 |
|
字节数 |
02 |
|
寄存器05H数据 |
高字节 |
33 |
低字节 |
44 |
|
CRC校验码 |
低字节 |
AD |
高字节 |
F3 |
|
例如: 主机从主机的地址01H,初始主机的地址05H读取,并保存主机的数据,主机发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
03 |
|
起始寄存器地址 |
高字节 |
00 |
低字节 |
05 |
|
寄存器数量 |
高字节 |
00 |
低字节 |
02 |
|
CRC校验 |
低字节 |
D4 |
高字节 |
0A |
|
如果从机保持寄存器05H、06H的数据为1122H、3344H,从机返回:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
03 |
|
字节数 |
04 |
|
寄存器05H数据 |
高字节 |
11 |
低字节 |
22 |
|
寄存器06H数据 |
高字节 |
33 |
低字节 |
44 |
|
CRC校验码 |
低字节 |
4B |
高字节 |
C6 |
|
例如: 主机将数据写到9988H给01H的主机、0050H的主机,而主机则发送:
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
06 |
|
寄存器地址 |
高字节 |
00 |
低字节 |
50 |
|
写入值 |
高字节 |
99 |
低字节 |
88 |
|
CRC校验 |
低字节 |
E3 |
高字节 |
ED |
|
机器的返回与主机的请求相同;
例如: 主机将 005H 、 2233H 数据保存到 01H 的主机地址,而主机则将它发送到两个主机的原始主机地址 0020H 。
主机发送 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
10 |
|
起始寄存器地址 |
高字节 |
00 |
低字节 |
20 |
|
寄存器数量 |
高字节 |
00 |
低字节 |
02 |
|
写入字节数 |
04 |
|
0000H 寄存器待写入 |
高字节 |
00 |
低字节 |
05 |
|
0001H 寄存器待写入 |
高字节 |
22 |
低字节 |
33 |
|
CRC校验 |
低字节 |
B9 |
高字节 |
03 |
|
函数代码10H操作从机器返回:
从机返回 |
发送数据(HEX) |
|
地址码 |
01 |
|
功能码 |
10 |
|
起始寄存器地址 |
高字节 |
00 |
低字节 |
20 |
|
寄存器数量 |
高字节 |
00 |
低字节 |
02 |
|
CRC校验 |
低字节 |
40 |
高字节 |
02 |
|
仿真演示:
本文由 在线网速测试 整理编辑,转载请注明出处。