網(wǎng)站設(shè)計(jì)app微信推廣方式有哪些
一、CRC的背景知識(shí)
1、什么是CRC
(1)CRC(Cyclic Redundancy Check),循環(huán)冗余校驗(yàn)
(2)什么是校驗(yàn),為什么需要校驗(yàn):數(shù)據(jù)傳輸,數(shù)據(jù)存儲(chǔ)過(guò)程中需要使用到的
(3)什么是冗余:表示比實(shí)際上要傳輸?shù)臄?shù)據(jù)還要多
(4)校驗(yàn)實(shí)現(xiàn)的關(guān)鍵:冗余少、運(yùn)算少、識(shí)錯(cuò)糾錯(cuò)能力強(qiáng)(有些算法只能識(shí)別錯(cuò)誤但是無(wú)法糾錯(cuò))
2、CRC原理介紹
(1)(N,K)碼:N=K(數(shù)據(jù)信息)+R(校驗(yàn)碼),K位信息碼,R位校驗(yàn)碼,N位總信息長(zhǎng)度
(2)CRC多項(xiàng)式:由K位信息碼計(jì)算得到R位校驗(yàn)碼的算法,以移位(左移,右移)和mod2(取余)為主的疊加
3、CRC的實(shí)現(xiàn)方法:軟件OR硬件
(1)純軟件實(shí)現(xiàn),靠CPU的運(yùn)算能力硬算。好處純軟件,壞處效率低(因?yàn)檎加肅PU資源)
(2)純軟件實(shí)現(xiàn),查表確定。好處純軟件效率高,壞處死板且占內(nèi)存(在表中查找相當(dāng)于在內(nèi)存中進(jìn)行搜索)
(3)硬件實(shí)現(xiàn),靠SoC內(nèi)置的CRC運(yùn)算模塊實(shí)現(xiàn)(內(nèi)部外設(shè)),類似于集成顯卡(STM32就是使用內(nèi)置的CRC)
(4)硬件實(shí)現(xiàn),靠SoC外置的運(yùn)算模塊實(shí)現(xiàn),類似于獨(dú)立顯卡,沒(méi)必要。
4、CRC使用場(chǎng)景
主要用于數(shù)據(jù)傳輸和存儲(chǔ)過(guò)程中隨機(jī)引起的錯(cuò)誤。但是CRC只能檢驗(yàn)錯(cuò)誤,但是無(wú)法糾錯(cuò)。
二、STM32使用CubeMX
1.CRC生成多項(xiàng)式計(jì)算
1.CRC16
1)CRC16表示最高位應(yīng)該是2的16次方
2)因?yàn)槭?6,所以最高位16的系數(shù)應(yīng)該是1,不能是0
3)0-15位,所以最高位16的系數(shù)不計(jì)算進(jìn)去
4)1*x^16(不計(jì)算進(jìn)去)+1*x^15+1*x^2+1*x^0=1000 0000 0000 0101=8005
2.配置
1.配置CRC
2.使用串口
3.HAL_CRC_Calculate? VS??HAL_CRC_Accumulate
Calculate和accumulate兩者不同
calculate的計(jì)算與上一次的計(jì)算結(jié)果無(wú)關(guān)
accumulate的計(jì)算結(jié)果是從上一次的計(jì)算結(jié)果來(lái)的
如果你的計(jì)算是分成多次計(jì)算來(lái)實(shí)現(xiàn),則調(diào)用【HAL_CRC_Accumulate】,如果算法是一次性實(shí)現(xiàn)完成則調(diào)用【HAL_CRC_Calculate 】
4.使用串口,添加串口相關(guān)的代碼
在usart.c文件中添加
#ifdef __GNUC__//當(dāng)前在Linux系統(tǒng)下#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else//在windows下#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/*** @brief Retargets the C library printf function to the USART.* @param None* @retval None*/
//PUTCHAR_PROTOTYPE 宏是一個(gè)用戶在使用HAL庫(kù)時(shí)可以自定義的宏,
//用于實(shí)現(xiàn) printf 函數(shù)的輸出重定向。
PUTCHAR_PROTOTYPE
//int fputc(int ch, FILE *f)
{/* Place your implementation of fputc here *//* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
5.代碼編寫
1.使用HAL_CRC_Calculate
/* USER CODE BEGIN PV */
uint32_t buf[]={0x11111111,0x22222222};//要發(fā)送的數(shù)據(jù),自己隨便定義一個(gè)
//存放crc
uint32_t crcValue=0;
/* USER CODE END PV */while (1){//調(diào)試printf("使用rcr成功");HAL_Delay(100);printf("CRC test\r\n");//使用crc算法將發(fā)送的值記錄起來(lái)crcValue=HAL_CRC_Calculate(&hcrc,buf,sizeof(buf)/sizeof(buf[0]));printf("crcValue=%x\r\n",crcValue);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}
2.驗(yàn)證傳輸過(guò)程是否正確
CRC在線計(jì)算 (lddgo.net)
與串口輸出的數(shù)值進(jìn)行比較,判斷是否正確---->結(jié)果正確
3.注意點(diǎn)
0和任何值異或,原值不變
不同點(diǎn):
1)結(jié)果異或值的不同
2)數(shù)據(jù)反轉(zhuǎn)不同