打印
[应用相关]

如何通俗的理解CRC校验并用C语言实现

[复制链接]
楼主: functions
手机看帖
扫描二维码
随时随地手机跟帖
21
functions|  楼主 | 2020-4-9 11:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
使用C语言实现CRC校验
算法1 —— 按位校验思想
CRC4
对于简单的CRC-4,实现代码如下:
#include <stdint.h>

#define CRC4_POLYNOMIAL 0xC8   /* 11011后面补0凑8位数:11011000*/

uint8_t CheckCrc4(uint8_t const message)
{
    uint8_t  remainder;        //余数
    uint8_t  i = 0;         //循环变量

    /* 初始化,余数=原始数据 */
    remainder = message;

    /* 从最高位开始依次计算  */
    for (i = 0; i < 8; i++)
    {
        if (remainder & 0x80)
        {
            remainder ^= POLYNOMIAL;
        }
        remainder = (remainder << 1);
    }

    /* 返回计算的CRC码 */
    return (remainder >> 4);
}

使用特权

评论回复
22
functions|  楼主 | 2020-4-9 11:09 | 只看该作者
测试代码如下:
#include <stdio.h>
int main(void)
{
    uint8_t dat = 0xB3;
    uint8_t crc = CheckCrc4(dat);

    printf("crc = %#x\n", crc);
    if(crc == 0x4)
    {
        printf("ok.\n");
    }
    else
    {
      printf("fail.\n");
    }

    return 0;
}

使用特权

评论回复
23
functions|  楼主 | 2020-4-9 11:11 | 只看该作者
运行结果如下:

使用特权

评论回复
24
functions|  楼主 | 2020-4-9 11:11 | 只看该作者
CRC8
根据一个字节数据的CRC校验实现思想,两个字节或多个字节的数据也是同样的道理,加一层循环就可以了,代码实现如下:
#define CRC8_POLYNOMIAL 0x31

uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value)
{
    uint8_t  remainder;        //余数
    uint8_t  i = 0, j = 0;  //循环变量

    /* 初始化 */
    remainder = initial_value;

    for(j = 0; j < 2;j++)
    {
        remainder ^= message[j];

        /* 从最高位开始依次计算  */
        for (i = 0; i < 8; i++)
        {
            if (remainder & 0x80)
            {
                remainder = (remainder << 1)^CRC8_POLYNOMIAL;
            }
            else
            {
                remainder = (remainder << 1);
            }
        }
    }

    /* 返回计算的CRC码 */
    return remainder;
}

使用特权

评论回复
25
functions|  楼主 | 2020-4-9 11:13 | 只看该作者
接下来用最开始在背景中提出的问题进行检,SHT30传感器的数据手册中给出了它计算CRC的生成多项式和初始值,并给出了一个示例,如图:

使用特权

评论回复
26
functions|  楼主 | 2020-4-9 11:14 | 只看该作者
接下来我们使用示例测试一下:

int main(void)
{
    char dat[2] = {0xBE,0xEF};
    uint8_t crc = CheckCrc8(dat, 0xFF);

    printf("crc = %#x\n", crc);
    if(crc == 0x92)
    {
        printf("ok.\n");
    }
    else
    {
      printf("fail.\n");
    }

    return 0;
}

使用特权

评论回复
27
functions|  楼主 | 2020-4-9 11:20 | 只看该作者
测试结果如下:

使用特权

评论回复
28
functions|  楼主 | 2020-4-9 11:22 | 只看该作者
算法2 —— 查表思想
生成表
首先需要编写一个程序,计算好所有的8位二进制数的CRC校验码,然后将它保存成一个256B大小的数组。

生成数组的代码如下:
int main(void)
{
    uint16_t i = 0;
    uint8_t crc = 0;

    for(i = 0; i < 256; i++)
    {
        crc = CheckCrc4(i);
        printf("0x%02x, ", crc);
        if((i+1)%16 == 0)
        {
            printf("\n");
        }
    }

    return 0;
}

使用特权

评论回复
29
functions|  楼主 | 2020-4-9 11:25 | 只看该作者
生成的表如图:

使用特权

评论回复
30
functions|  楼主 | 2020-4-9 11:25 | 只看该作者
查找表
将这张表保存为一个数组,然后编写新的校验CRC的程序:
#include <stdio.h>
#include <stdint.h>

uint8_t CRC4_TABLE[256] = {
    //……这里数据太多,省略
};
int main(void)
{
    uint8_t dat = 0xB3;
    uint8_t crc = CRC4_TABLE[dat];      //直接查表

    printf("crc = %#x\n", crc);
    if(crc == 0x04)
    {
        printf("ok.\n");
    }
    else
    {
      printf("fail.\n");
    }
    return 0;
}

使用特权

评论回复
31
functions|  楼主 | 2020-4-9 11:28 | 只看该作者
两种C语言实现方法比较

使用特权

评论回复
32
functions|  楼主 | 2020-4-9 11:28 | 只看该作者
移植第三方库 —— LibCRC
CRC的计算确实是一个非常头疼的事情,所以国外有大神开源了一个库专门用于CRC计算 —— LibCRC。

Libcrc是一个C语言实现的多平台MIT许可CRC库,其官网链接为:www.libcrc.org,其Github仓库为:LibCRC。

有兴趣的读者可以移植分享一下~

使用特权

评论回复
33
functions|  楼主 | 2020-4-9 11:29 | 只看该作者
使用硬件CRC校验电路
在STM32L4上有一个专门的CRC校验外设,可以直接使用STM32CubeMX激活CRC校验,然后使用HAL调用进行校验,后续在使用硬件IIC和硬件CRC驱动SHT30这篇**中会有介绍,敬请期待~

使用特权

评论回复
34
functions|  楼主 | 2020-4-9 11:30 | 只看该作者
**作者:  Mculover666
**链接:  http://www.mculover666.cn/posts/1935373145/
版权声明:  本博客所有**除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mculover666 !

使用特权

评论回复
35
labasi| | 2020-5-7 13:54 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
36
paotangsan| | 2020-5-7 13:55 | 只看该作者
为什么会有这么多种类的算法呢

使用特权

评论回复
37
renzheshengui| | 2020-5-7 13:55 | 只看该作者
感觉就像是破译密码

使用特权

评论回复
38
wakayi| | 2020-5-7 13:56 | 只看该作者
有没有一种说法就是哪种算法更好呢 或者说更适用于什么环境

使用特权

评论回复
39
wowu| | 2020-5-7 13:56 | 只看该作者
解释的条理清晰

使用特权

评论回复
40
hotpower| | 2020-5-23 10:58 | 只看该作者
www.hotcrc.com 它可以自动生成任意CRC表格或算法

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则