Arduino中的迴圈冗餘校驗 (CRC)


CRC 代表迴圈冗餘校驗 (Cyclic Redundancy Check)。簡單來說,它是一種用於檢測接收到的訊息中錯誤的演算法。其思想類似於奇偶校驗,但它更加健壯。

如果傳送器正在向接收器傳送資料包,傳送器將根據資料包上的一些多項式計算來計算 CRC 程式碼,並將其附加到資料包中。接收器將對資料包執行相同的計算,並檢查生成的 CRC 是否與資料包中包含的 CRC 匹配。如果兩者匹配,則傳輸中沒有引入錯誤,並且可以安全地進一步處理資料包。如果不匹配,則接收到的資料包有錯誤,應將其丟棄。

CRC 的確切工作原理超出了本文的範圍。有一些庫可用於在 Arduino 中執行 CRC 計算。這裡有一個示例。AVR 也有一個原生 CRC 庫

示例

您可以隨意探索這些庫。但是,我們不會使用任何這些庫。相反,我們將從頭編寫一個函式來返回位元組陣列的 16 位 CRC。該實現將使用 Fletcher 校驗和。它非常健壯,甚至可以檢測資料是否排序不正確。此外,該演算法非常易於實現:

uint16_t checksumCalculator(uint8_t * data, uint16_t length)
{
   uint16_t curr_crc = 0x0000;
   uint8_t sum1 = (uint8_t) curr_crc;
   uint8_t sum2 = (uint8_t) (curr_crc >> 8);
   int index;
   for(index = 0; index < length; index = index+1)
   {
      sum1 = (sum1 + data[index]) % 255;
      sum2 = (sum2 + sum1) % 255;
   }
   return (sum2 << 8) | sum1;
}
void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
   Serial.println();
   uint8_t buf[10] = {1,2,3,4,5,6,7,8,9,0};
   uint16_t crc = checksumCalculator(buf,10);
   Serial.print("Calculated CRC is: ");Serial.println(crc, HEX);
}
void loop() {
   // put your main code here, to run repeatedly:
}

輸出

序列埠監視器輸出為:

如您所見,我們使用了0x0000作為初始化值。您可以使用不同的初始值,前提是接收器和傳送器都遵循相同的約定。

您將 sum1 初始化為初始值的低位元組,將sum2初始化為高位元組。然後,您繼續將連續的資料位元組新增到sum1中,並將sum1的值新增到sum2中,始終保持值小於 255(使用模運算子)。最後,您返回一個 16 位數字,其中sum2為高位元組,sum1 為低位元組。

更新於:2021年7月24日

4K+ 次瀏覽

開啟您的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.