以前在嵌入式開發中進行CRC校驗一般通過軟件算法實現,TM4C1294自帶CRC校驗單元,但坑比較多,發出來供使用時參考
CRC單元只有一個寄存器,7個字段需要配置
INIT:初始值;
SIZE: 選擇校驗數據是8位還是32位;
RESINV:輸出按位取反;
OBR:輸出字節反轉,例如B0[7:0]-->B0[0:7]
BR:輸入字節反轉,例如B0[7:0]-->B0[0:7]
ENDIAN:大小端控制
TYPE:校驗類型,即選擇生成多項式
看着簡單,發現不瞭解CRC校驗算法還是一臉懵逼
那簡單瞭解下CRC算法,首先CRC校驗算法有很多種,根據生成校驗數據位數的多少分爲CRC-8、CRC-16、CRC-32等很多種,在嵌入式裏面最常用的是CRC-16這種,但CRC-16根據生成多項的不同又分爲幾種,最常用的兩種也是TM4C1924支持的兩種是
CRC-16/CCITT : 生成多項式是0x1021
CRC-16/MODBUS:生成多項式是0x8005
而這兩種之中最最常用的就是CRC-16/MODBUS,下面以此爲例講下寄存器該如何配置
到現在知道了TYPE和SIZE該怎麼配置,再加上單個字節數據校驗不存在大小端的問題,ENDIAN也知道怎麼配置了,但還有幾個關鍵寄存器不知道,難道真的要把CRC算法瞭解一遍,也有簡便的方法,實用軟件CRC Caculator,下載鏈接在此https://download.csdn.net/download/crazin/10670926
在這個軟件裏面,選擇不同的的CRC校驗算法右側有該算法的相關信息,例如CRC-16/MODBUS的信息如下
跟上面配置寄存器是對應的
Init:0XFFFF 對應初始值是全1,即初始值寄存器INIT應該設置爲0x3;
RefOut:True,對應輸出字節反轉,即OBR=1;
RefIn:True,對應輸入字節反轉,即BR=1;
XorOut:0x0000,對應輸出保持不變不按位取反,即RESINV=0;
CRC-16/MODBUS的配置寄存器應配置如下:
HWREG(CCM0_BASE+CCM_O_CRCCTRL)=0x7180;
//INIT = 0x3; 初始值 0XFF
//SIZE = 1; 8bit
//RESINV =0; 輸出異或值0X0000
//OBR =1; RefOut 輸出按字節反轉,例如B0[7:0]-->B0[0:7]
//BR =1; RefIn 輸入按字節反轉,
//ENDIAN = 0;
//TYPE = 0; Polynomial 0x8005
CRC校驗直接調用官方提供的驅動函數CRCDataProcess即可搞定。
其實還有一點問題,校驗完未按進行按位反轉的結果是放在CRC SEED裏面的,按位反轉後的結果是放在 CRC Post Processing Result 裏面的(CRC-16/MODBUS結果因未按位取反,故結果兩個寄存器結果一致)
之所以這樣是方面進行連續校驗,比如你要校驗20個字節,你可以先校驗10個字節,然後用存在CRC SEED裏面的校驗結果再與後面十個字節進行校驗。
需要注意的是CRC單元默認是要進行連續校驗的,因爲雖然在初始化的時候把INIT設置爲了1,但INIT是會自動清零的,也即往CRCDIN 裏面出入第一個要校驗的字節之後INIT就會自清零,下次將使用CRC SEED的值作爲初始值,這也是CRC校驗算法的基本流程,對第一個字節做校驗,將校驗結果作爲初始值在對第二個字節進行校驗。
所以正確的校驗程序應該在每次開始校驗前對INIT重新賦值或者對CRC SEED寫爲0xFFFF;
常用CRC-32的校驗信息如下:
對應的CRC-32的配置寄存器應配置如下:
HWREG(CCM0_BASE+CCM_O_CRCCTRL)=0x63b2;
//INIT = 0x3; 初始值 0XFFFFFFFF
//SIZE = 0; 32bit
//RESINV =1; 輸出異或值0XFFFFFFFF
//OBR =1; RefOut 輸出按字節反轉,例如B0[7:0]-->B0[0:7]
//BR =1; RefIn 輸入按字節反轉,
//ENDIAN = 0x03;
//TYPE = 0X2; Polynomial 0x4C11DB7