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