灵天读写器CRC16计算方法(.NET、C语言)

2019-08-02 12:25:28 3084

一体机读写器/分体式读写器AT指令CRC校验方法,暂时只有C#版本,C语言版本

适用型号:

LT-DS302 DS312 DS309 DS310,LT-DS814 DS818 DS8112 DS8116,LT-DS509 DS512,LT-DS322

C#版本

        public class CRC
    {
        private static int POLYNOMIAL = 0x8408;
        private static int PRESET_VALUE = 0xFFFF;

        public static int crc16(string hex)
        {
            byte[] data = HexStringToByteArray(hex);
            int current_crc_value = PRESET_VALUE;
            for (int i = 0; i < data.Length; i++)
            {
                current_crc_value ^= data[i] & 0xFF;
                for (int j = 0; j < 8; j++)
                {
                    if ((current_crc_value & 1) != 0)
                    {
                        current_crc_value = (current_crc_value >> 1) ^ POLYNOMIAL;
                    }
                    else
                    {
                        current_crc_value = current_crc_value >> 1;
                    }
                }
            }
            return current_crc_value;
        }
        /// <summary>
        /// 16进制数组字符串转换
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }
    }

调用示例:

string input = "1500010301010C300833B2DDD90140000000002A80BE";//读写器AT指令返回值,也可用于指令发送校验CRC

int bytes = CRC.crc16(input);

// bytes=0;bytes等于0表示通过,其他值不通过!


C语言版本:

CRC16的C语言算法:
#define PRESET_VALUE 0xFFFF
#define POLYNOMIAL  0x8408
unsigned int uiCrc16Cal(unsigned char const  * pucY, unsigned char ucX)
{
     unsigned char ucI,ucJ;
     unsigned short int  uiCrcValue = PRESET_VALUE;
         for(ucI = 0; ucI < ucX; ucI++)
        {
               uiCrcValue = uiCrcValue ^ *(pucY + ucI);
             for(ucJ = 0; ucJ < 8; ucJ++)
         {
                  if(uiCrcValue & 0x0001)
              {
                      uiCrcValue = (uiCrcValue >> 1) ^ POLYNOMIAL;
              }
                  else
              {
                      uiCrcValue = (uiCrcValue >> 1);
              }
            }
    }
return uiCrcValue;
}

说明:

pucY是要计算CRC16的字符数组的入口,ucX是字符数组中字符个数。

上位机收到数据的时候,只要把收到的数据按以上算法进行计算CRC16,结果为0x0000表明数据正确。