1. 目的

   电流数据采集器是RS485 Modbus协议,想通过java实现串口数据的采集,因为涉及到串口通信的CRC校验,所以需要通过java来实现对采集的电流值进行校验,确保每次读到的电流值都是正常的。

2. 什么是ModbusCRC16校验

  Modbus协议是一种串行通信协议,被广泛用于设备之间的通信。Modbus协议可以支持多种电气接口和传输介质,包括但不限于RS-232、RS-422、RS-485、以太网(TCP/IP)等。
   CRC16校验是一种基于多项式的校验方法,其核心思想是将数据视为一个长的二进制数,通过特定的生成多项式来计算一个短的余数,这个余数就是CRC校验码

3. CRC16校验步骤

  1. 初始化预置一个16位的寄存器为十六进制0xFFFF,称此寄存器为CRC寄存器,多项式为0xA001。
  2. 数据处理
    2.1 将第一个8位二进制数据(通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器。
    2.2 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位。
    2.3 如果移出位为0,继续右移;如果移出位为1,将CRC寄存器与多项式0xA001异或
    2.4 重复上述步骤,直到处理完8次(即一个字节的所有位
  3. 重复处理重复步骤2,处理通信信息帧的下一个字节,直到所有字节处理完毕
  4. 结果处理最终寄存器中的值即为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与实际一致。

点击阅读全文
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐