
java实现ModbusCRC16校验
电流数据采集器是RS485 Modbus协议,想通过java实现串口数据的采集,因为涉及到串口通信的CRC校验,所以需要通过java来实现对采集的电流值进行校验,确保每次读到的电流值都是正常的。Modbus协议是一种串行通信协议,被广泛用于设备之间的通信。,其核心思想是将数据视为一个长的二进制数,2. 什么是ModbusCRC16校验。,称此寄存器为CRC寄存器,3. CRC16校验步骤。CRC1
·
1. 目的
电流数据采集器是RS485 Modbus协议,想通过java实现串口数据的采集,因为涉及到串口通信的CRC校验,所以需要通过java来实现对采集的电流值进行校验,确保每次读到的电流值都是正常的。
2. 什么是ModbusCRC16校验
Modbus协议是一种串行通信协议,被广泛用于设备之间的通信。Modbus协议可以支持多种电气接口和传输介质,包括但不限于RS-232、RS-422、RS-485、以太网(TCP/IP)等。
CRC16校验是一种基于多项式的校验方法,其核心思想是将数据视为一个长的二进制数,通过特定的生成多项式来计算一个短的余数,这个余数就是CRC校验码。
3. CRC16校验步骤
- 初始化:预置一个16位的寄存器为十六进制0xFFFF,称此寄存器为CRC寄存器,多项式为0xA001。
- 数据处理
2.1 将第一个8位二进制数据(通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器。
2.2 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位。
2.3 如果移出位为0,继续右移;如果移出位为1,将CRC寄存器与多项式0xA001异或。
2.4 重复上述步骤,直到处理完8次(即一个字节的所有位) - 重复处理:重复步骤2,处理通信信息帧的下一个字节,直到所有字节处理完毕。
- 结果处理:最终寄存器中的值即为CRC16校验值。
4. 代码实现
public static Byte[] CRC_calculate(byte[] data){
int POLYNOMIAL = 0xA001; // CRC-16/IBM 生成多项式0xA001
int INITIAL_VALUE = 0xFFFF; // 初始值0xFFFF
int crc = INITIAL_VALUE;
for (byte b : data) { //遍历所有的字节
crc ^= (b & 0xFF);
for (int i = 8; i != 0; i--) {
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= POLYNOMIAL;
} else {
crc >>= 1;
}
}
}
List<Byte> list = new ArrayList<>();
// MODBUS的低位在前
list.add((byte) (crc & 0xff)); // 低位
list.add((byte) (crc >> 8)); // 高位
return list.toArray(new Byte[0]); // 转换为Byte数组
}
//主函数
public class Main {
public static void main(String[] args) {
byte[] data = {0x01, 0x03, 0x00, 0x20, 0x00, 0x01};
//byte[] data = {0x01, 0x03, 0x02, 0x27, 0x10};
Byte[] crc = CRC_calculate(data);
System.out.println("CRC-16 Modbus length: " + crc.length);
System.out.println("CRC-16 Modbus1: " + String.format("%X", crc[0]));
System.out.println("CRC-16 Modbus2: " + String.format("%X", crc[1]));
}
}
5. 结果比对
运行的结果:
由结果可以看出,85 C0与实际一致。
运行的结果:
由结果可以看出,A2 78与实际一致。
点击阅读全文
更多推荐
所有评论(0)