Bläddra i källkod

CRC16 操作工具类提交,动态生成开关锁指令类

donggaosheng 3 år sedan
förälder
incheckning
ee2eddb65f

+ 114 - 0
zd-modules/zd-modules-laboratory/src/main/java/com/zd/laboratory/utils/CRCCHECK.java

@@ -0,0 +1,114 @@
+package com.zd.laboratory.utils;
+
+public class CRCCHECK {
+
+    //开锁后缀
+    private static final String OPEN_LOCK_ORDER_SUFFIX=" 05 00 01 EE 00";
+    //关锁后缀
+    private static final String CLOSE_LOCK_ORDER_SUFFIX=" 05 00 01 DD 00";
+    //读锁后缀
+    private static final String READ_LOCK_ORDER_SUFFIX=" 01 00 01 00 01";
+
+    /**
+     * CRC16_MODBUS:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或
+     * 以上计算步骤中的多项式0xA001是0x8005按位颠倒后的结果。
+     * 0x8408是0x1021按位颠倒后的结果。
+     * @param s 需要输入十六进制字符串
+     * @return 结果数据CRC16 modbus格式
+     */
+    private static String getCRC16Result(String s){
+        int CRC = 0x0000ffff;
+        for (int i=0;i<s.length();i=i+2){
+            int CRCL=CRC&0x000000FF;//低八位
+            int CRCH=CRC&0x0000FF00;//高八位
+            String CRCIn = s.substring(i,i+2);
+            int a = Integer.parseInt(CRCIn,16);//待处理数据转16进制
+            CRC=CRCH+CRCL^a;
+            for(int j=0;j<8;j++){
+                if((CRC&0x0001)==0){
+                    CRC=CRC>>1;
+                }else {
+                    CRC>>=1;
+                    CRC=CRC^0xA001;
+                }
+            }
+        }
+        //      交换
+        int CRCL=CRC&0x000000FF;//低八位
+        int CRCH=CRC&0x0000FF00;//高八位
+        CRC=CRCL<<8|CRCH>>8;//最好用按位与,别用加
+        String hexString=Integer.toHexString(CRC).toUpperCase();
+        //给crc加空格格式
+        String regex = "(.{2})";
+        hexString=hexString.replaceAll(regex, "$1 ");
+        return hexString;
+    }
+
+    public static void main(String args[]){
+        Integer bit=1;
+        System.out.println(getOpenLockOrder(bit));
+        System.out.println(getCloseLockOrder(bit));
+        System.out.println(getReadLockOrder(bit));
+    }
+
+    /**
+     * 根据地址位动态生成开锁指令
+     * @param bit
+     * @return
+     */
+    public static String getOpenLockOrder(Integer bit){
+        return getCommandByType(bit,1);
+    }
+
+    /**
+     * 根据地址位动态生成关锁指令
+     * @param bit
+     * @return
+     */
+    public static String getCloseLockOrder(Integer bit){
+        return getCommandByType(bit,2);
+    }
+
+    /**
+     * 根据地址位动态生成读指令
+     * @param bit
+     * @return
+     */
+    public static String getReadLockOrder(Integer bit){
+        return getCommandByType(bit,3);
+    }
+
+    private static String getCommandByType(Integer bit,Integer type){
+        String command=getCommand(bit);
+        if(type==1){
+            command=command+OPEN_LOCK_ORDER_SUFFIX;
+        }
+        if(type==2){
+            command=command+CLOSE_LOCK_ORDER_SUFFIX;
+        }
+        if(type==3){
+            command=command+READ_LOCK_ORDER_SUFFIX;
+        }
+        String commandRep = command.replace(" ","");
+        String crcRes=getCRC16Result(commandRep);
+        String finalCommand=command+" "+crcRes;
+        return finalCommand;
+    }
+
+    /**
+     * 通用的地址位表头计算
+     * @param bit
+     * @return
+     */
+    private static String getCommand(Integer bit){
+        String cls=Integer.toHexString(bit).toUpperCase();
+        String changeCls="";
+        if(cls.length()>1){
+            changeCls=cls;
+        }
+        if(cls.length()==1){
+            changeCls="0"+cls;
+        }
+        return changeCls;
+    }
+}