Modbus RTU 是一种串行通信协议,通常用于工业自动化系统中的设备间通信。它使用二进制编码,支持多个设备在同一通信线路上进行通信。以下是一些关于 Modbus RTU 的信息:
- Modbus RTU 是 Modbus 协议的一种变体,它使用 RS-485 串行通信标准。
- Modbus RTU 使用 CRC 校验来保证数据传输的完整性和正确性。
- Modbus RTU 支持多种数据类型,包括整数、浮点数、布尔值等。
- Modbus RTU 通常被用于控制器、传感器、执行器等设备之间的通信。
Modbus比其他通信协议使用的更广泛的主要原因有:
公开发表并且无版权要求 易于部署和维护
对供应商来说,修改移动本地的比特或字节没有很多限制 Modbus允许多个 (大约240个) 设备连接在同一个网络上进行通信,举个例子,一个由测量温度和湿度的装置,并且将结果发送给计算机。
Modbus支持的具体协议有:Modbus TCP、Modbus UDP、Modbus RTU、ModbusRtuOverTcp、Modbus Ascii等。支持Modbus的设备厂高非常多,三菱、西门子等在不同的设备模块上都有支持。
1 modbus 通讯数据格式
地址码 |
功能码 |
数据区 |
校验码 |
1个字节1 |
1个字节 |
N个字节 |
6位CRC |
2 功能码
功能码 |
描述 |
说明 |
MOUBUS地址 |
01 |
读输出线圈寄存器 |
位操作 |
00001 ~ 09999 |
02 |
读离散输入寄存器 |
位操作 |
10001 ~ 19999 |
03 |
读保持(输出)寄存器 |
字操作 |
40001 ~ 49999 |
04 |
读输入寄存器 |
字操作 |
30001 ~ 39999 |
05 |
写单线圈寄存器 |
位操作 |
00001 ~ 09999 |
06 |
写单线圈保持寄存器 |
字操作 |
40001 ~ 49999 |
07 |
读取异常状态 |
获得8个内部线圈的逻辑状态 |
|
10 |
写多路寄存器 |
字操作 |
|
15 |
写多线圈寄存器 |
位操作 |
00001 ~ 09999 |
16 |
写多个保持寄存器 |
字操作 |
40001 ~ 49999 |
17 |
报告从机标识 |
可使主机判断从机标识的类型及其该从机运行指示灯的状态 |
3.格式
数据区格式不固定,一般需要查看从机设备的通讯手册
数据区格式示例:
开始编号/寄存器地址 |
数据个数 |
数据1 |
…… |
数据n |
2个字节 |
2个字节 |
2个字节 |
2个字节 |
2个字节 |
4.CRC校验算法步骤
第一步:设置CRC变量存储器初始值位0xFFFF;
第二步:把第一个参与校验的数据和CRC变量的低八位进行异或运算,结果仍存到CRC存储器中;
第三步:把CRC右移一位,最高位补0;
第四步:检查刚移出的最低位b0,如果b0=1,则CRC变量和0xA001进行异或运算,结果仍存在CRC变量存储器中,然后执行下一步。如果b0=0,则直接执行下一步;
第五步:重复3、4两步,只到右移8次。这样第一个数据处理就完成了,结果仍存在CRC变量存储器中。
第六步:重复2~5步,处理下一个数据,只到参与校验的数据均处理完毕。 注:最后获得的16位CRC校验值,在传输时,低八位在前,高八位在后;
CRC校验算法C#语言程序
/// <summary>
/// CRC16_Modbus效验
/// </summary>
/// <param name="byteData">要进行计算的字节数组</param>
/// <returns>计算后的数组</returns>
public static byte[] ToModbus(byte[] byteData)
{
byte[] CRC = new byte[2];
UInt16 wCrc = 0xFFFF;
for (int i = 0; i < byteData.Length; i++)
{
wCrc ^= Convert.ToUInt16(byteData[i]);
for (int j = 0; j < 8; j++)
{
if ((wCrc & 0x0001) == 1)
{
wCrc >>= 1;
wCrc ^= 0xA001;//异或多项式
}
else
{
wCrc >>= 1;
}
}
}
CRC[1] = (byte)((wCrc & 0xFF00) >> 8);//高位在后
CRC[0] = (byte)(wCrc & 0x00FF); //低位在前
return CRC;
}