CRC16的C语言算法：
#include #include #include #include #define PRESET_VALUE 0xFFFF
#define POLYNOMIAL  0x8408

typedef  unsigned char byte;

typedef union name{
    int len;
    unsigned char ucx;
} name;


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

void hexToBytes(const std::string& hex, byte* bytes){
    int bytelen = hex.length()/2;
    std::string strByte;
    unsigned int n;
    for(int i = 0; i < bytelen; i++){
        strByte = hex.substr(i*2, 2);
        sscanf(strByte.c_str(), "%x", &n);
        bytes[i]=n;
    }
}


int main()
{
    std::string hex="1500010101010ce28011700000020cc282e26d84d652";
    int bytelen=hex.length()/2;
    byte *ptr=new byte[bytelen];
    hexToBytes(hex, ptr);

    unsigned int ret = uiCrc16Cal(ptr, bytelen);
      
    std::cout << ret << std::endl;
    delete [] ptr;
    return 0;
}

说明：

pucY是要计算CRC16的字符数组的入口(需转换字节数组)，ucX是字符数组中字符个数。

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