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;
}