單片機C語言實現的CRC算法

2020-12-12 電子產品世界

1 引言
循環冗餘碼CRC檢驗技術廣泛應用於測控及通信領域。CRC計算可以靠專用的硬體來實現,但是對於低成本的微控制器系統,在沒有硬體支持下實現CRC檢驗,關鍵的問題就是如何通過軟體來完成CRC計算,也就是CRC算法的問題。
這裡將提供三種算法,它們稍有不同,一種適用於程序空間十分苛刻但CRC計算速度要求不高的微控制器系統,另一種適用於程序空間較大且CRC計算速度要求較高的計算機或微控制器系統,最後一種是適用於程序空間不太大,且CRC計算速度又不可以太慢的微控制器系統。
2 CRC簡介
CRC校驗的基本思想是利用線性編碼理論,在發送端根據要傳送的k位二進位碼序列,以一定的規則產生一個校驗用的監督碼(既CRC碼)r位,並附在信息後邊,構成一個新的二進位碼序列數共(k+r)位,最後發送出去。在接收端,則根據信息碼和CRC碼之間所遵循的規則進行檢驗,以確定傳送中是否出錯。
16位的CRC碼產生的規則是先將要發送的二進位序列數左移16位(既乘以 )後,再除以一個多項式,最後所得到的餘數既是CRC碼,如式(2-1)式所示,其中B(X)表示n位的二進位序列數,G(X)為多項式,Q(X)為整數,R(X)是餘數(既CRC碼)。
(2-1)
求CRC碼所採用模2加減運算法則,既是不帶進位和借位的按位加減,這種加減運算實際上就是邏輯上的異或運算,加法和減法等價,乘法和除法運算與普通代數式的乘除法運算是一樣,符合同樣的規律。生成CRC碼的多項式如下,其中CRC-16和CRC-CCITT產生16位的CRC碼,而CRC-32則產生的是32位的CRC碼。本文不討論32位的CRC算法,有興趣的朋友可以根據本文的思路自己去推導計算方法。
CRC-16:(美國二進位同步系統中採用)
CRC-CCITT:(由歐洲CCITT推薦)
CRC-32:

接收方將接收到的二進位序列數(包括信息碼和CRC碼)除以多項式,如果餘數為0,則說明傳輸中無錯誤發生,否則說明傳輸有誤,關於其原理這裡不再多述。用軟體計算CRC碼時,接收方可以將接收到的信息碼求CRC碼,比較結果和接收到的CRC碼是否相同。

3 按位計算CRC
對於一個二進位序列數可以表示為式(3-1):
(3-1)
求此二進位序列數的CRC碼時,先乘以 後(既左移16位),再除以多項式G(X),所得的餘數既是所要求的CRC碼。如式(3-2)所示:
(3-2)
可以設: (3-3)
其中 為整數, 為16位二進位餘數。將式(3-3)代入式(3-2)得:

(3-4)
再設: (3-5)
其中 為整數, 為16位二進位餘數,將式(3-5)代入式(3-4),如上類推,最後得到:
(3-6)
根據CRC的定義,很顯然,十六位二進位數 既是我們要求的CRC碼。
式(3-5)是編程計算CRC的關鍵,它說明計算本位後的CRC碼等於上一位CRC碼乘以2後除以多項式,所得的餘數再加上本位值除以多項式所得的餘數。由此不難理解下面求CRC碼的C語言程序。*ptr指向發送緩衝區的首字節,len是要發送的總字節數,0x1021與多項式有關。
unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned char i;
unsigned int crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc0x8000)!=0) {crc*=2; crc^=0x1021;} /* 餘式CRC乘以2再求CRC */
else crc*=2;
if((*ptri)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
按位計算CRC雖然代碼簡單,所佔用的內存比較少,但其最大的缺點就是一位一位地計算會佔用很多的處理器處理時間,尤其在高速通訊的場合,這個缺點更是不可容忍。因此下面再介紹一種按字節查表快速計算CRC的方法。
4 按字節計算CRC
不難理解,對於一個二進位序列數可以按字節表示為式(4-1),其中 為一個字節(共8位)。
(4-1)
求此二進位序列數的CRC碼時,先乘以 後(既左移16位),再除以多項式G(X),所得的餘數既是所要求的CRC碼。如式(4-2)所示:
(4-2)
可以設: (4-3)
其中 為整數, 為16位二進位餘數。將式(4-3)代入式(4-2)得:
(4-4)
因為:
(4-5)
其中 是 的高八位, 是 的低八位。將式(4-5)代入式(4-4),經整理後得:
(4-6)
再設: (4-7)
其中 為整數, 為16位二進位餘數。將式(4-7)代入式(4-6),如上類推,最後得:
(4-8)
很顯然,十六位二進位數 既是我們要求的CRC碼。
式(4-7)是編寫按字節計算CRC程序的關鍵,它說明計算本字節後的CRC碼等於上一字節餘式CRC碼的低8位左移8位後,再加上上一字節CRC右移8位(也既取高8位)和本字節之和後所求得的CRC碼,如果我們把8位二進位序列數的CRC全部計算出來,放如一個表裡,採用查表法,可以大大提高計算速度。由此不難理解下面按字節求CRC碼的C語言程序。*ptr指向發送緩衝區的首字節,len是要發送的總字節數,CRC餘式表是按0x11021多項式求出的。


相關焦點

  • 用C語言實現CRC校驗計算
    CRC的實現分為硬體和軟體兩種方法,其中軟體實現的關鍵在於計算速度。如果單純模擬硬體實現方法,則計算速度較慢。筆者在編制一個數據通訊軟體中,運用了一種新穎的查表法計算CRC,速度很快,效果極佳。組合值只有256種可能,因此可利用硬體模擬算法先算好它們的CRC值預先填入一張表中,該表的每一單元對應相對值的CRC。這樣就可以通過查表法來計算CRC值,以便大大提高CRC運算的速度。下面給出用C語言編制的計算程序。
  • 單片機C語言實現求平方根算法
    C語言中要求平方根,可以在頭文件中加入#include <math.h>.然後調用sqrt(n);函數即可。但在單片機中調用此函數無疑會耗費大量資源和時間,是極不合適的。在此,總結下網上常見的四種單片機常用開方根算法:對於擁有專門的乘除法指令的單片機,可採用以下兩種方法:1、二分法對於一個非負數n,它的平方根不會小於大於(n/2+1)(謝謝@linzhi-cs提醒)。在[0, n/2+1]這個範圍內可以進行二分搜索,求出n的平方根。
  • CRC校驗你會嗎?計算、校驗、C語言實現,三步教你輕鬆搞定
    算法簡介CRC計算CRC校驗CRC計算的C語言實現本篇文章介紹CRC校驗的原理和實現方法。CRC算法簡介循環冗餘校驗(Cyclic Redundancy Check, CRC)是一種根據網絡數據包或計算機文件等數據產生簡短固定位數校驗碼的一種信道編碼技術,主要用來檢測或校驗數據傳輸或者保存後可能出現的錯誤。
  • 40位以內任意長度的CRC計算及校驗的實現
    不同crc碼的生成多項式各不相同,crc碼的比特數也不同,且在有的通信協議中要求將餘數寄存器先初始化為全0,另外的則須初始化為全1。因此,在程序設計時必須充分利用crc碼的共性及所用dsp的指令特點。2 用tms320c5000實現不同crc計算的設計思想本文引用地址:http://www.eepw.com.cn/article/21134.htm crc碼的計算及校驗都用到模2的多項式除法,而多項式除法可以採用帶反饋的移位寄存器來實現,因此,用dsp來實現crc計算的關鍵是通過dsp來模擬一個移位寄存器(也就是模擬手寫多項式除法)。
  • CRC校驗碼在單片機中的程序實現的求取
    對於8位的單片機系統,要實現CRC通信就必須編寫生成CRC碼的指令程序,且由於單片機的程序存儲器很少、運算速度也比較低,因此要求程序代 碼儘量少,算法必須簡單。下面將以CRC—CCITT標準為例來介紹CRC通信碼的單片機實現過程。
  • 寫出高效優美的單片機C語言代碼
    下面發一些我在網上看到的技巧和自己的一些經驗來和大家分享;1、如果可以的話少用庫函數,便於不同的mcu和編譯器間的移植2、選擇合適的算法和數據結構應該熟悉算法語言,知道各種算法的優缺點,具體資料請參見相應的參考資料,有很多計算機書籍上都有介紹。
  • CRC-16校驗和實現
    ❝從Qt源碼摘取的CRC-16校驗和實現。
  • 單片機常用的14個C語言算法
    算法的描述:是對要解決一個問題或要完成一項任務所採取的方法和步驟的描述,包括需要什麼數據(輸入什麼數據、輸出什麼結果)、採用什麼結構、使用什麼語句以及如何安排這些語句等。通常使用自然語言、結構化流程圖、偽代碼等來描述算法。
  • 關於CRC8/CRC16/CRC32,你要找的全部在這
    ▍CRC的實現按照前面章節的「CRC原理」來做C語言實現,就通過數據移位和異或算得。那需要怎麼優化算法呢?那就將多項式預先算個表出來,查表吧。2.於是我做了個通用版,滿足各種算法,其中用了宏定義的奇技淫巧。
  • 為什麼C語言是最適合單片機編程的高級語言!
    為什麼還在用C語言編程?答案是:C語言是最適合單片機編程的高級語言。 這個問題的意思應該是:現在有很多很好用的高級語言,如java,python等等,為什麼這些語言不能用來編寫單片機程序呢?那麼這個問題的答案就是:不是不能,而是不合適。
  • PIC單片機C語言程序實例
    包含了各種數據結構,如整型、數據類型、指針類型和聯合類型等,用來實現各種數據結構的運算。C語言的運算符有34種,範圍很寬,靈活使用各種運算符可以實現難度極大的運算。      C語言能直接訪問硬體的物理地址,能進行位(bit)操作。兼有高級語言和低級語言的許多優點。      它既可用來編寫系統軟體,又可用來開發應用軟體,已成為一種通用程序設計語言。
  • CRC 循環冗餘校驗算法
    奇偶校驗優點也很明顯,它很簡單,因此可以用硬體來實現,這樣可以減少軟體的負擔。因此,奇偶校驗也被廣泛的應用著。累加和校驗另一種常見的校驗方式是累加和校驗。所謂累加和校驗實現方式有很多種,最常用的一種是在一次通訊數據包的最後加入一個字節的校驗數據。
  • 單片機C語言編程心得
    經過查找資料得知,.H文件就是頭文件,估計就是Head的意思吧,這是規範程序結構化設計的需要,既可以實現大型程序的模塊化,又可以實現根各模塊的連接調試。1、.H文件介紹:在單片機C程序設計中,項目一般按功能模塊化進行結構化設計。
  • 最適合單片機編程的高級語言,除了C語言,別無選擇!
    單片機為什麼還在用C語言編程?答案是:C語言是最適合單片機編程的高級語言。 這個問題的意思應該是:現在有很多很好用的高級語言,如java,python,VC等等,為什麼這些語言不能用來編寫單片機程序呢?那麼這個問題的答案就是:不能不能,而是不合適。
  • AVR單片機CRC校驗碼的查表與直接生成
    AVR高速嵌入式單片機功能強大,在無線數據傳輸應用方面具有很大優勢。本文基於 Atmega128高速嵌入式單片機,實現32位CRC校驗碼的直接生成法和查表生成法;根據實驗結果,分析兩種方法的特點。這裡,假定待發送的二進位數據段為g(x),生成多項式為 m(x),得到的CRC校驗碼為c(x)。   CRC校驗碼的編碼方法是用待發送的二進位數據g(x)除以生成多項式m(x),將最後的餘數作為CRC校驗碼,實現步驟如下。    ① 設待發送的數據塊是m位的二進位多項式 g(x),生成多項式為r階的m(x)。
  • PIC單片機C語言程序設計(4)
    2.if語句  if 語句也稱為條件語句,是C 語言中轉移語句之一。在設計C 語言程序時,常常要根據某些條件以決定程序運行的流向,這時就需要if 語句來實現。
  • 常用的CRC 循環冗餘校驗算法
    奇偶校驗優點也很明顯,它很簡單,因此可以用硬體來實現,這樣可以減少軟體的負擔。因此,奇偶校驗也被廣泛的應用著。累加和校驗另一種常見的校驗方式是累加和校驗。所謂累加和校驗實現方式有很多種,最常用的一種是在一次通訊數據包的最後加入一個字節的校驗數據。這個字節內容為前面數據包中全部數據的忽略進位的按字節累加和。
  • 幾種常見的校驗算法
    下面就介紹幾種常見的校驗算法。一、校驗和校驗和是最基本,也是嵌入式工程師最常用的一種校驗算法,其實現方法很簡單,簡單到只有幾行代碼。實現的方式方法很多,不同的程式語言,不同的應用有所不同,下面以C語言8位校驗和為例:uint8_t CheckSum(uint8_t *Buf, uint8_t Len){ uint8_t i = 0; uint8_t sum = 0; uint8_t checksum = 0; for(i=0; i<Len
  • 單片機常用的14個C語言算法,看過的都成了大神!
    單片機常用的14個C語言算法,看過的都成了大神! 算法(Algorithm):計算機解題的基本思想方法和步驟。
  • 基於C語言STC89C52單片機電子密碼鎖的設計與仿真
    它採用高可靠性的STC89C52單片機來實現開鎖和密碼的識別,採用具備I2C總線接口的E2PROM晶片來完成密碼的存儲,通過1602液晶顯示器提示程序運行狀態和使用步驟,利用蜂鳴器模擬報警,發光二極體模擬鎖的開關。該系統用C語言編寫程序,與彙編語言相比具備更好的移植性和可讀性,便於修改和增減功能。