GD32开发实战指南第18章CRC
开发环境:
MDK:Keil 5.30
开发板:GD32F207I-EVAL
MCU:GD32F207IK18.1 CRC的校验原理
循环冗余校验(CRC)计算单元是根据固定的生成多项式得到任一32位全字的CRC计算结果。在其他的应用中, CRC技术主要应用于核实数据传输或者数据存储的正确性和完整性。标准EN/IEC 60335-1即提供了一种核实闪存存储器完整性的方法。 CRC计算单元可以在程序运行时计算出软件的标识,之后与在连接时生成的参考标识比较,然后存放在指定的存储器空间。那么首先来看看CRC校验原理。18.1.1基本原理
CRC检验原理实际上就是在一个p位二进制数据序列之后附加一个r位二进制检验码(序列),从而构成一个总长为n p r位的二进制序列;附加在数据序列之后的这个检验码与数据序列的内容之间存在着某种特定的关系。如果因干扰等原因使数据序列中的某一位或某些位发生错误,这种特定关系就会被破坏。因此,通过检查这一关系,就可以实现对数据正确性的检验。几个基本概念
1、帧检验序列FCS(Frame Check Sequence):为了进行差错检验而添加的冗余码。
2、多项式模2运行:实际上是按位异或(Exclusive OR)运算,即相同为0,相异为1,也就是不考虑进位、借位的二进制加减运算。如:10011011 + 11001010 = 01010001。
3、生成多项式(generator polynomial):当进行CRC检验时,发送方与接收方需要事先约定一个除数,即生成多项式,一般记作G(x)。生成多项式的最高位与最低位必须是1。常用的CRC码的生成多项式有:
每一个生成多项式都可以与一个代码相对应,如CRC8对应代码:100110001。18.1.2 CRC检验码的计算
设信息字段为K位,校验字段为R位,则码字长度为N(N=K+R)。设双方事先约定了一个R次多项式g(x),则CRC码:
V(x)=A(x)g(x)=xRm(x)+r(x)
其中: m(x)为K次信息多项式, r(x)为R-1次校验多项式。
这里r(x)对应的代码即为冗余码,加在原信息字段后即形成CRC码。
r(x)的计算方法为:在K位信息字段的后面添加R个0,再除以g(x)对应的代码序列,得到的余数即为r(x)对应的代码(应为R-1位;若不足,而在高位补0)。
计算示例:
设需要发送的信息为M = 1010001101,产生多项式对应的代码为P = 110101,R 5。在M后加5个0,然后对P做模2除法运算,得余数r(x)对应的代码:01110。故实际需要发送的数据是101000110101110。
18.1.3错误检测
当接收方收到数据后,用收到的数据对P(事先约定的)进行模2除法,若余数为0,则认为数据传输无差错;若余数不为0,则认为数据传输出现了错误,由于不知道错误发生在什么地方,因而不能进行自动纠正,一般的做法是丢弃接收的数据。
【注】几点说明:
1、CRC是一种常用的检错码,并不能用于自动纠错。
2、只要经过严格的挑选,并使用位数足够多的除数 P,那么出现检测不到的差错的概率就很小很小。
3、仅用循环冗余检验 CRC 差错检测技术只能做到无差错接受(只是非常近似的认为是无差错的),并不能保证可靠传输。18.2 GD32中的CRC
所有的GD32芯片都内置了一个硬件的CRC计算模块,可以很方便地应用到需要进行通信的程序中,这个CRC计算模块使用常见的、在以太网中使用的计算多项式:
写成16进制就是:0x04C11DB7
使用这个内置CRC模块的方法非常简单,既首先复位CRC模块(设置CRC_CR=0x01),这个操作把CRC计算的余数初始化为0xFFFFFFFF;然后把要计算的数据按每32位分割为一组数据字,并逐个地把这组数据字写入CRC_DR寄存器(既下图中的绿色框),写完所有的数据字后,就可以从CRC_DR寄存器(既下图中的兰色框)读出计算的结果。
下面是用C语言描述的这个计算模块的算法,大家可以把它放在通信的另一端,对通信的正确性进行验证:DWORD dwPolynomial = 0x04c11db7; DWORD cal_crc(DWORD *ptr, int len) { DWORD xbit; DWORD data; DWORD CRC = 0xFFFFFFFF; // init while (len--) { xbit = 1 << 31; data = *ptr++; for (int bits = 0; bits < 32; bits++) { if (CRC & 0x80000000) { CRC <<= 1; CRC ^= dwPolynomial; } else CRC <<= 1; if (data & xbit) CRC ^= dwPolynomial; xbit >>= 1; } } return CRC; }
有几点需要说明:
1)上述算法中变量CRC,在每次循环结束包含了计算的余数,它始终是向左移位(既从最低位向最高位移动),溢出的数据位被丢弃。
2)输入的数据始终是以32位为单位,如果原始数据少于32位,需要在低位补0,当然也可以高位补0。
3)假定输入的DWORD数组中每个分量是按小端存储。
4)输入数据是按照最高位最先计算,最低位最后计算的顺序进行。
例如:
如果输入0x44434241,内存中按字节存放的顺序是:0x41, 0x42, 0x43, 0x44。计算的结果是:0xCF534AE1
如果输入0x41424344,内存中按字节存放的顺序是:0x44, 0x43, 0x42, 0x41。计算的结果是:0xABCF9A6318.3 CRC寄存器描述数据寄存器(CRC_DRTA)
CRC_DATA用于接收待计算的新数据,直接将其写入即可。刚写入的数据不能被读出来,因为读取该寄存器得到的是上次CRC计算的结果。独立数据寄存器(CRC_FDATA)
注:此寄存器不参与CRC计算,可以存放任何数据。控制寄存器(CRC_CTL)
CRC_CTL用来复位CRC_DATA寄存器,设置其值为0xFFFFFFFF,然后该位被硬件自动清零。该位对CRC_FDATA寄存器没有影响。18.4 CRC具体代码实现
代码很简单。/* brief main function param[in] none param[out] none retval none */ int main(void) { //systick init sysTick_init(); //usart init 115200 8-N-1 com_init(COM1, 115200, 0, 1); printf("CRC Test "); /* Enable CRC clock */ rcu_periph_clock_enable(RCU_CRC); /* Compute the CRC of "DataBuffer" */ CRCValue = crc_block_data_calculate((uint32_t *)DataBuffer, BUFFER_SIZE); printf("r 32-bit CRC check code : 0x%X ", CRCValue); while(1) { delay_ms(1000); } }
就使用了crc_block_data_calculate()函数,传入一个要计算的数据和大小,就得到了计算的CRC值。18.5实验现象
将编译好的程序下载到板子中,通过串口助手可以看到如下现象。
然后使用CRC计算工具来计算。
可以看到和软件计算的一致。
值得注意的是,STM32的硬件CRC的结果异或值是0x00000000。
【注】关于CRC的更多内容可以自行查阅相关资料,笔者这里推荐一篇文章`A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS`,感兴趣的朋友自己去看看吧。
有没有这样一段文字,让你因此爱上一座城?究竟怎样的文字,会让我因此爱上一座城?没错,就是下面这段当年我在阴暗潮湿的淤泥中等待,等待着一线光明漫漫长夜,你们终于来了你们在船上激情澎湃众志成城,我在水下静静聆听喜极而泣,你们
突击检查!无锡这两家人气饭店后厨曝光春天是无锡最美的时候宜人的气候和浪漫的樱花吸引了全国各地的游客不少游客都会选择到景区附近的饭店享受美食为切实做好旅游景区食品安全保障工作加强旅游旺季食品安全监管无锡经济开发区市场监
中国拉斯维加斯澳门五一假期即将来临,计划出游的朋友们都在提早规划出现目的地,今天谈谈出游澳门需要注意哪些方面(现身说法)第一点,兵马未动粮草先行,对了,就是旅行经费。一定注意随身过关港币是不能超过2
厦门!木棉花开!木棉花孩子们将掉落的木棉花摆出各种造型。木棉树下同学会。却是南中春色别,满城都是木棉花。最近很多市民抬头观望,为盛开的木棉花驻足。继广州的木棉花满城绽放引发市民在各网络平台晒美图之
性暗示这颗毒瘤,正在幼儿圈疯狂生长,家长却谈性色变!前言中国教育更为含蓄内敛传统。因此,在我们面对性这个字眼时,大多数人都会避之不及。甚至谈性色变。可是现在软色情文化盛行,在我们逃避问题时,各种成人性暗示的物品,竟悄然出现在幼儿圈中
备孕的妈妈们,千万要注意了!输卵管相关疾病导致的不孕约占女性不孕症的三分之一,输卵管积水是输卵管相关疾病一个常见的组成部分,值得我们好好了解。输卵管积水为慢性输卵管炎症中较为常见的类型。水可以有两种来源1输卵
儿医说丨养成好睡眠习惯,宝宝安睡到天亮记者焦守广通讯员王昆吴伟宝宝得新冠后睡眠开始不好了,经常醒,宝宝最近晚上睡觉老是哭闹!宝宝经常要抱着睡,放下就醒,咋回事呀什么原因导致宝宝睡眠不好?家长朋友们最先想到的可能是缺钙。
八年前的回忆孕期最难忘的事如果不是这个征文活动,我是不会去回忆八年前的事了。现在儿子已经八岁半了,回想当年怀孕的时候,我就只有一个字吐。唉,那九个多月的日子是女人一生中最不容易的时候了。图片来
甲流退烧后一直咳嗽是怎么回事?要及时就医还是自己吃点药就行?甲型流感的患者可出现咳嗽咳痰发热等症状,如咳嗽加重时,应及时就诊,主要治疗方法有一般治疗药物治疗等。宝宝甲流后咳嗽,主要是进行一般治疗以及药物治疗。1。一般治疗主要是做好日常护理,
流感下,孕产妇该如何破解?湖南日报全媒体记者周阳乐通讯员洪翰近来流感流行,孕产妇该如何破解?3月20日,记者邀请湖南省妇幼保健院内科专家为孕产妇们一一作答。流感,全称流行性感冒,是一种以高热乏力头痛咳嗽全身
胎儿猛长期是什么时候?能长多少斤?在孕早期胎儿发育很慢,肚子也就不怎么会变大,孕中期胎儿体重才开始加速增长,但是还不是生长最快的时候哦,孕晚期是胎儿体重增长的最快时期。孕早中期是胎宝宝发育的关键期,孕晚期就是胎宝宝