0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何实现对通信数据的CRC计算

Q4MP_gh_c472c21 来源:嵌入式ARM 作者:嵌入式ARM 2020-09-29 14:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

最近的工作中,要实现对通信数据的CRC计算,所以花了两天的时间好好研究了一下,周末有时间整理了一下笔记。

一个完整的数据帧通常由以下部分构成:

校验位是为了保证数据在传输过程中的完整性,采用一种指定的算法对原始数据进行计算,得出的一个校验值。接收方接收到数据时,采用同样的校验算法对原始数据进行计算,如果计算结果和接收到的校验值一致,说明数据校验正确,这一帧数据可以使用,如果不一致,说明传输过程中出现了差错,这一帧数据丢弃,请求重发。

常用的校验算法有奇偶校验、校验和、CRC,还有LRC、BCC等不常用的校验算法。

以串口通讯中的奇校验为例,如果数据中1的个数为奇数,则奇校验位0,否则为1。

例如原始数据为:0001 0011,数据中1的个数(或各位相加)为3,所以奇校验位为0。这种校验方法很简单,但这种校验方法有很大的误码率。假设由于传输过程中的干扰,接收端接收到的数据是0010 0011,通过奇校验运算,得到奇校验位的值为0,虽然校验通过,但是数据已经发生了错误。

校验和同理也会有类似的错误:

一个好的校验校验方法,配合数字信号编码方式,如(差分)曼彻斯特编码,(不)归零码等对数据进行编码,可大大提高通信的健壮性和稳定性。例如以太网中使用的是CRC-32校验,曼彻斯特编码方式。本篇文章介绍CRC校验的原理和实现方法。

CRC算法简介

循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。

CRC校验计算速度快,检错能力强,易于用编码器等硬件电路实现。从检错的正确率与速度、成本等方面,都比奇偶校验等校验方式具有优势。因而,CRC 成为计算机信息通信领域最为普遍的校验方式。常见应用有以太网/USB通信,压缩解压,视频编码,图像存储,磁盘读写等。

CRC参数模型

不知道你是否遇到过这种情况,同样的CRC多项式,调用不同的CRC计算函数,得到的结果却不一样,而且和手算的结果也不一样,这就涉及到CRC的参数模型了。计算一个正确的CRC值,需要知道CRC的参数模型。

一个完整的CRC参数模型应该包含以下信息:WIDTH,POLY,INIT,REFIN,REFOUT,XOROUT。

NAME:参数模型名称。

WIDTH:宽度,即生成的CRC数据位宽,如CRC-8,生成的CRC为8位

POLY:十六进制多项式,省略最高位1,如 x8 + x2 + x + 1,二进制为1 0000 0111,省略最高位1,转换为十六进制为0x07。

INIT:CRC初始值,和WIDTH位宽一致。

REFIN:true或false,在进行计算之前,原始数据是否翻转,如原始数据:0x34 =0011 0100,如果REFIN为true,进行翻转之后为0010 1100= 0x2c

REFOUT:true或false,运算完成之后,得到的CRC值是否进行翻转,如计算得到的CRC值:0x97 =1001 0111,如果REFOUT为true,进行翻转之后为11101001= 0xE9。

XOROUT:计算结果与此参数进行异或运算后得到最终的CRC值,和WIDTH位宽一致。

通常如果只给了一个多项式,其他的没有说明则:INIT=0x00,REFIN=false,REFOUT=false,XOROUT=0x00。

常用的21个标准CRC参数模型:

CRC校验在电子通信领域非常常用,可以说有通信存在的地方,就有CRC校验:

美信(MAXIM)的芯片DS2401/DS18B20,都是使用的CRC-8/MAXIM模型

SD卡或MMC使用的是CRC-7/MMC模型

Modbus通信使用的是CRC-16/MODBUS参数模型

USB协议中使用的CRC-5/USB和CRC-16/USB模型

STM32自带的硬件CRC计算模块使用的是CRC-32模型

至于多项式的选择,初始值和异或值的选择,输入输出是否翻转,这就涉及到一定的编码和数学知识了。感兴趣的朋友,可以了解一下每个CRC模型各个参数的来源。至于每种参数模型的检错能力、重复率,需要专业的数学计算了,不在本文讨论的范畴内。

CRC计算

好了,了解了CRC参数模型知识,下面手算一个CRC值,来了解CRC计算的原理。

问:原始数据:0x34,使用CRC-8/MAXIN参数模型,求CRC值?

答:根据CRC参数模型表,得到CRC-8/MAXIN的参数如下:

POLY = 0x31 = 0011 0001(最高位1已经省略) INIT = 0x00 XOROUT = 0x00 REFIN = TRUE REFOUT = TRUE

有了上面的参数,这样计算条件才算完整,下面来实际计算:

0.原始数据 = 0x34 =0011 0100,多项式 = 0x31 =1 0011 00011.INIT = 00,原始数据高8位和初始值进行异或运算保持不变。 2.REFIN为TRUE,需要先对原始数据进行翻转:0011 0100 > 0010 11003.原始数据左移8位,即后面补8个0:0010 11000000 00004.把处理之后的数据和多项式进行模2除法,求得余数: 原始数据:0010 1100 0000 0000 = 10 1100 0000 0000多项式:1 0011 0001模2除法取余数低8位:1111 10115.与XOROUT进行异或,1111 1011 xor 0000 0000 = 1111 10116.因为REFOUT为TRUE,对结果进行翻转得到最终的CRC-8值:1101 1111= 0xDF 7.数据+CRC:0011 0100 1101 1111= 34DF,相当于原始数据左移8位+余数。

模2除法求余数:

验证手算结果:

可以看出是一致的,当你手算的结果和工具计算结果不一致时,可以看看INIT,XOROUT,REFINT,REFOUT这些参数是否一致,有1个参数不对,计算出的CRC结果都不一样。

CRC校验

上面通过笔算的方式,讲解了CRC计算的原理,下面来介绍一下如何进行校验。

按照上面CRC计算的结果,最终的数据帧:0011 0100 1101 1111= 34DF,前8位0011 0100是原始数据,后8位1101 1111是 CRC结果。

接收端的校验有两种方式,一种是和CRC计算一样,在本地把接收到的数据和CRC分离,然后在本地对数据进行CRC运算,得到的CRC值和接收到的CRC进行比较,如果一致,说明数据接收正确,如果不一致,说明数据有错误。

另一种方法是把整个数据帧进行CRC运算,因为是数据帧相当于把原始数据左移8位,然后加上余数,如果直接对整个数据帧进行CRC运算(除以多项式),那么余数应该为0,如果不为0说明数据出错。

而且,不同位出错,余数也不同,可以证明,余数与出错位数的对应关系只与CRC参数模型有关,而与原始数据无关。

CRC计算的C语言实现

无论是用C还是其他语言,实现方法网上很多,这里我找了一个基于C语言的CRC计算库,里面包含了常用的21个CRC参数模型计算函数,可以直接使用,只有crcLib.c和crcLib.h两个文件。

GitHub地址:https://github.com/whik/crc-lib-c

使用方法非常简单:

#include #include #include "crcLib.h" int main() { uint8_t LENGTH = 10; uint8_t data[LENGTH]; uint8_t crc; for(int i = 0; i < LENGTH; i++)   {        data[i] = i*5;        printf("%02x ", data[i]);   }    printf(" ");    crc = crc8_maxim(data, LENGTH);    printf("CRC-8/MAXIM:%02x ", crc);    return 0; }

计算结果:

CRC计算工具

下面这几款工具都可以自定义CRC算法模型,而且都有标准CRC模型可供选择。如果自己用C语言或者Verilog实现校验算法时,非常适合作为标准答案进行验证。

在线计算:www.ip33.com/crc.html

离线计算工具:CRC_Calc v0.1.exe或者GCRC.exe

格西CRC计算器:

总结

CRC校验并不能100%的检查出数据的错误,非常低的概率会出现CRC校验正确但数据中有错误位的情况。这和CRC的位数,多项式的选择等等有很大的关系,所以在实际使用中尽量选择标准CRC参数模型,这些多项式参数都是经过理论计算得出的,可以提高CRC的检错能力。CRC校验可以检错,也可以纠正单一比特的错误,你知道纠错的原理吗?

参考资料

www.cnblogs.com/liushui-sky/p/9962123.html

segmentfault.com/a/1190000018094567

责任编辑:xj

原文标题:CRC校验你会吗?计算、校验、C语言实现,三步教你轻松搞定

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144553
  • CRC校验
    +关注

    关注

    0

    文章

    84

    浏览量

    15842

原文标题:CRC校验你会吗?计算、校验、C语言实现,三步教你轻松搞定

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    芯源的CRC硬件计算谁用过吗?MCU的CRC你们喜欢用硬件的还是软件的啊?

    芯源的CRC硬件计算谁用过吗?MCU的CRC你们喜欢用硬件的还是软件的啊?
    发表于 12-01 08:25

    AS32系列MCU芯片中CRC计算模块的应用介绍

    、执行器动作异常甚至整个控制系统宕机。循环冗余校验(CRC)作为一种高效的错误检测技术,如同数据传输与存储过程中的"安全校验屏障",持续保障MCU与外部设备交互数据的准确性。本文将系统阐述国科安芯推出的AS32系列MCU芯片中的
    的头像 发表于 11-21 15:20 1093次阅读
    AS32系列MCU芯片中<b class='flag-5'>CRC</b><b class='flag-5'>计算</b>模块的应用介绍

    硬件循环冗余校验(CRC)模块介绍

    CRC是一种错误检测码,用于检测数据传输或存储中的意外更改。它通过对数据应用特定的算法生成一个固定长度的校验值。这个校验值附加在数据后面,接收方可以重新
    发表于 11-21 07:39

    CRC校验的原理和应用

    原理: CRC校验将数据视为一个二进制多项式,用一个预先定义好的生成多项式(Generator Polynomial) 进行模2除法,得到的余数作为CRC校验码。 例如:数据多项式 ÷
    发表于 11-14 06:48

    CRC校验的本质和物理意义

    工业控制系统中,Modbus RTU协议的CRC校验如同通信网络的\"免疫系统\",某石化厂DCS系统曾因CRC计算错误导致0.3%的数据
    发表于 11-13 07:58

    8种常用的CRC算法分享

    CRC 计算单元可按所选择的算法和参数配置来生成数据流的 CRC 码。有些应用中,可利用 CRC 技术来验证
    发表于 11-13 07:25

    RVMCU课堂「19」: 手把手教你玩转RVSTAR—CRC计算

    在之前的内容里,我们介绍了很多通信协议,不过仅讲解了数据的收发方法,而在实际的通信系统中,除了要实现收发外,还要尽量保证数据尽量不出差错。为
    发表于 10-30 07:49

    使用PLC实现ModbusRTU主站通信

    Modbus RTU是工业自动化领域常用的串行通信协议,基于RS485、RS422或RS232物理层,采用主从通信模式,主设备主动发起请求,从设备被动响应。其数据帧含从机地址、功能码、数据
    的头像 发表于 08-19 13:59 1550次阅读
    使用PLC<b class='flag-5'>实现</b>ModbusRTU主站<b class='flag-5'>通信</b>

    ST25TA手册上的RF帧CRC计算,ISO/IEC13239中哪一个呢?

    手册上看到是这样的说明,nfc forum 4标签的指令格式带有的CRC应该要按这个来计算,发送。有用过这算法的吗
    发表于 08-13 06:45

    储能BMS通信“卡壳”?CAN转EtherCAT让电池数据“跑起来”

    的“高速通信需求”。 实战案例:让电池数据“不迟到” 某储能电站曾遇棘手问题:200节电池组的BMS数据延迟达500ms,导致SOC( State of Charge)计算偏差超5%。
    发表于 07-18 15:32

    第十八章 浅谈循环冗余校验(CRC)计算单元

    本篇文章介绍了CRC(循环冗余校验),其计算单元用 CRC-32多项式,32位数据寄存器,4个AHB时钟周期完成计算。含
    的头像 发表于 05-29 11:00 920次阅读
    第十八章 浅谈循环冗余校验(<b class='flag-5'>CRC</b>)<b class='flag-5'>计算</b>单元

    并行CRC实现

    电子发烧友网站提供《并行CRC实现.pdf》资料免费下载
    发表于 05-20 17:26 0次下载

    求助,关于ad7616序列器模式+crc的两个问题求解

    是对的吗?并且这个crc我用所有数据代入得不到这个值。这个crc值应该怎么计算?软件序列器模式和硬件序列器模式都是一样的现象。有人能帮我解答吗?感谢支持!
    发表于 04-15 08:23

    基于Verilog语言实现CRC校验

    CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对
    的头像 发表于 03-24 10:36 2164次阅读
    基于Verilog语言<b class='flag-5'>实现</b><b class='flag-5'>CRC</b>校验

    使用stm32u535实现usb hid custom上下位机通信功能时遇到了从上位机(计算机)接收数据有个别错误的问题,怎么解决?

    最近使用stm32u535系列单片机实现usb hid custom上下位机通信功能时遇到了从上位机(计算机)接收数据有个别错误的问题,如下图所示,用usb调试工具发送
    发表于 03-12 07:16