1、CRC計算公式
所有的STM32芯片都內置了一個硬件的CRC計算模塊,可應用到通信程序中,這個CRC計算模塊使用常見的、在以太網中使用的計算多項式:
X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2 + X + 1
寫成16進制就是:0x04C11DB7
2、使用這個內置CRC模塊操作步驟:
復位CRC模塊(設置CRC_CR=0x01),這個操作把CRC計算的余數初始化為0xFFFFFFFF
把要計算的數據按每32位分割為一組數據字,并逐個地把這組數據字寫入CRC_DR寄存器(既下圖中的綠色框)
寫完所有的數據字后,就可以從CRC_DR寄存器(既下圖中的蘭色框)讀出計算的結果。
注意:雖然讀寫操作都是針對CRC_DR寄存器,但實際上是訪問的不同物理寄存器。
3、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,在每次循環(huán)結束包含了計算的余數,它始終是向左移位(既從最低位向最高位移動),溢出的數據位被丟棄。
2)、輸入的數據始終是以32位為單位,如果原始數據少于32位,需要在低位補0,當然也可以高位補0。
3)、假定輸入的DWORD數組中每個分量是按小端存儲。
4)、輸入數據是按照最高位最先計算,最低位最后計算的順序進行。
例如:
如果輸入0x44434241,內存中按字節(jié)存放的順序是:0x41, 0x42, 0x43, 0x44。計算的結果是:0xCF534AE1
如果輸入0x41424344,內存中按字節(jié)存放的順序是:0x44, 0x43, 0x42, 0x41。計算的結果是:0xABCF9A63