CRC16 CCITT 代码 - 如何适配制造商样本源

CRC16 CCITT code - how to adapt manufacturer sample source

我尝试创建一个可以从 RFID reader 模块读取数据的代码。为此,我需要进行 CRC16 CCITT 计算。

我在 reader 制造商应用技术数据表 http://www.card-sys.com/manuals/framer_eng.pdf

中找到了 CRC16 校验和计算的 C 源代码

不幸的是,这只是代码的一部分,不是完整的工作示例。

当 RFID reader 处于自动模式时,它会在每次读取标签时自动发送 11 个字节。 CRC - 该值是使用除最后两个字节 CRCH(CRC 高字节)和 CRCL(CRC 低字节)之外的所有字节计算的。

当我从 reader 读取 RFID 标签时,我传输了 11 个字节...即(十六进制)01 0B 03 01 06 87 DB C7 FF E5 68。最后两个字节 E5 68 是消息的 CRC16 校验和。为了确认数据没问题,我需要在目标点针对 01 0B 03 01 06 87 DB C7 FF 计算相同的 CRC16。

我尝试将所有内容整合到一起,但我没有太多 C 编程经验,而且我的代码无法运行。

这里是源代码:

#include <stdio.h>
#include <stdlib.h>

// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
    {
        int i, byte;
        unsigned short C;

        *CRC = 0;
        for (byte = 1; byte <= Bytes; byte ++, Data ++)
            {
                C = ((*CRC >> 8) ^ *Data) << 8;
                for (i = 0; i < 8; i ++)
                    {
                        if (C & 0x8000)
                            C = (C << 1) ^ 0x1021;
                        else
                            C = C << 1;
                    }
                *CRC = C ^ (*CRC << 8);
            }
    }


int main(void)
    {
        puts("Test...");

        unsigned char * Data16="10ac0501ff";
        unsigned short * CRC=0;
        unsigned char Bytes16=4;

        CRC16(Data16,CRC,Bytes16);

        puts(CRC);

        return EXIT_SUCCESS;
    }

我想做的是学习如何在工作示例中使用制造商代码 - 即如何计算 crc16。

你能帮我解决这个问题吗?谢谢。

我使用您的源代码创建了以下程序。

#include <stdio.h>
#include <stdlib.h>

// CRC16 from Netronix datasheet
void CRC16(unsigned char * Data, unsigned short * CRC, unsigned char Bytes)
{
    int i, byte;
    unsigned short C;

    *CRC = 0;
    for (byte = 1; byte <= Bytes; byte++, Data++)
    {
        C = ((*CRC >> 8) ^ *Data) << 8;
        for (i = 0; i < 8; i++)
        {
            if (C & 0x8000)
                C = (C << 1) ^ 0x1021;
            else
                C = C << 1;
        }
        *CRC = C ^ (*CRC << 8);
    }
}


int main(void)
{

    // When I read RFID tag from a reader I got 11 bytes transferred... i.e.
    // (hex)01 0B 03 01 06 87 DB C7 FF E5 68.
    // Last two bytes E5 68 are crc16.
    // In order to confirm the data is OK I need to calculate the same crc16
    // against 01 0B 03 01 06 87 DB C7 FF at the destination point.
    unsigned char  Data16[] = { 0x01, 0x0B, 0x03, 0x01, 0x06, 0x87, 0xDB, 0xC7, 0xFF };
    unsigned short CRC = 0;
    unsigned char Bytes16 = 9;

    CRC16(Data16, &CRC, Bytes16);

    printf(" CRC calculated is %x\n", CRC);

    return EXIT_SUCCESS;
}

输出为 CRC calculated is e568

我做了一些更改。

首先是我使用的数据来自您对 RFID 标签 reader 输出的评论。

When I read RFID tag from a reader I got 11 bytes transferred... i.e. (hex) 01 0B 03 01 06 87 DB C7 FF E5 68. Last two bytes E5 68 are crc16. In order to confirm the data is OK I need to calculate the same crc16 against 01 0B 03 01 06 87 DB C7 FF at the destination point. You are probably right about the Data16[]... I will change this later today and let you know what current status is. Thanks for helping :)

我使用了不包括校验和的数据长度。所以帧数据中的长度是 0x0B 或 11,因为校验和是 2 个字节,我使用 11 - 2 或 9 作为长度。

最后我把变量CRC的定义改成了unsigned short CRC = 0;并且在调用CRC函数的时候,我使用了CRC16(Data16, &CRC, Bytes16);.

中运算符的地址

串行传输的帧格式

根据您引用的文档,有两种类型的帧或消息,其格式如下:

Command frame:

  • module address (1 byte) unique address of each module in network
  • frame length (1 byte) full length of frame (includes 2 byte checksum)
  • command (1 byte) command code which is an even value
  • parameters (variable length) optional parameters depending on command
  • CRCH (1 byte) upper byte of the CRC16
  • CRCL (1 byte) lower byte of the CRC16

Answer frame:

  • module address (1 byte) unique address of each module in network
  • frame length (1 byte) full length of frame (includes 2 byte checksum)
  • answer(1 byte) answer code which is an odd value
  • parameters (variable length) optional parameters depending on command
  • operation code (1 byte) command execution status
  • CRCH (1 byte) upper byte of the CRC16
  • CRCL (1 byte) lower byte of the CRC16