如何使用此代码计算CRC?

时间:2017-08-15 10:12:28

标签: c crc

我试图在设备和我的服务器之间进行无线电通信。设备中的数据如下所示:

fa-00-01-09-16-aa-00-14-10-01-01-00-01-16-ff-ff-ff-ff-ff-ff-cb-14

其中最后两个字节是CRC。现在我需要向我的设备发送回复并计算其CRC。设备的数据表并没有多说,它只提供C函数来计算它,但我很难理解我应该为这个函数提供什么

unsigned int CRC_Check(unsigned char *ucCRC_Buf, unsigned char ucBufLength)
{
    unsigned int uiX, uiY, uiCRC;
    unsigned char ucStart = 0;
    uiCRC = 0xFFFF; //set all 1

    if (ucBufLength <= 0 || ucStart > ucBufLength)
    {
        uiCRC = 0;
    }
    else
    {
        ucBufLength += ucStart;

        for (uiX = (unsigned int)ucStart; uiX < ucBufLength; uiX++)
        {
            uiCRC = (unsigned int)(uiCRC ^ ucCRC_Buf[uiX]);

            for (uiY = 0; uiY <= 7; uiY++)
            {
                if((uiCRC & 1) != 0)
                    uiCRC = (unsigned int)((uiCRC >> 1)^0xA001);
                else
                    uiCRC = (unsigned int)(uiCRC >> 1);
            }
        }
    }

    return uiCRC;
}

数据表还说&#34; CRC检查是在数据包上进行的,不包括起始码&amp;检查代码&#34;这意味着第一个字节(0xFA)和最后两个字节(CRC)。

现在,我试图理解它所期望的unsigned char *ucCRC_Bufunsigned char ucBufLength。从我的主要人物中我试图做到:

unsigned int crc = CRC_Check("00010916aa0014100101000116ffffffffffff",38);
printf("%d\n", crc);

与开头的字符串相同(没有第一个和最后两个字节),我期待CB14(十六进制)。但它给出了不同的数字(54016(dec),即D300(十六进制))。

知道我做错了吗?

2 个答案:

答案 0 :(得分:6)

可能你必须自己传递字节,而不是它们的十六进制表示。

更改

unsigned int crc=CRC_Check("00010916aa0014100101000116ffffffffffff",38);

unsigned int crc=CRC_Check("\x00\x01\x09\x16\xaa\x00\x14\x10\x01\x01\x00\x01\x16\xff\xff\xff\xff\xff\xff", 19);

请注意,只有19个字节。 (谢谢@alk)

答案 1 :(得分:2)

数据服务器正在以Hexadecimal格式发送。

您正在将字符串传递给函数,这会给您错误的结果。

验证的正确方法是:

unsigned char data[] = {0x00,0x01,0x09,0x16,0xaa,0x00,0x14,0x10,0x01,0x01,0x00,0x01,0x16,0xff,0xff,0xff,0xff,0xff,0xff}

unsigned int CRC = CRC_Check(&data[0],19);