注:genpoly為generator polynomial的合成調(diào),在程序中用作“生成多項式”寄存器。
1.1 直接模2除法CRC實現(xiàn)方式
對16位的CRC而言,用信息段作被除數(shù),生成多項式(本文1021H,CCITT標(biāo)準(zhǔn))作除數(shù),進(jìn)行模2除法所產(chǎn)生的余數(shù)(2字節(jié))即為CRC校驗值,且CRC校驗只間余數(shù)而不管商是多少。發(fā)送時將校驗值連在信息段的后面一起發(fā)送。在接收端,接收方只需把接收到的CRC校驗值連同信息一,作為新的信息段并對其進(jìn)行相同的CRC運算(只比發(fā)送時多2字節(jié))。若得到的新余數(shù)(校驗值)為0,則表明接收到的信息段和CRC都無差錯;反之,說明信息段或CRC有錯,應(yīng)做相應(yīng)處理。所以CRC的編碼和譯碼并沒有本質(zhì)的區(qū)別。程序如下:USHORT crc(USHORT data,USHORT genpoly,USHORT accum)
{// data:數(shù)據(jù),所用信息字的第一個字節(jié);genpoly:CRC多項式,如1021H;accum:累加器的值,第一次賦0,以后放每次校驗結(jié)果。
data<<=8; //信息字節(jié)左移到高字節(jié)
for(int i=8;i>0;i--){
if((data^accum)&0x800) //如果(data異或accum)的最高位是1
accum=(accum<<1)^genpoly; //移位與genpoly異域
else accum<<=1; //否則僅移位
data<<=1; //將信息字的下一位升格
}
return accum; //返回用作下一個信息字校驗的累加器值
}
1.2 快速CRC實現(xiàn)方式
直接模2除法CRC方式雖編程簡單,但效率不高。采用方式方式,要使用16位的多項式及兩字節(jié)的累加器,對每一信息位(bit)累加器都要移位一次,再根據(jù)移位結(jié)果判斷是否作異式;每一字節(jié)重復(fù)8位,運算速度相對較慢,不符合計算機按比特進(jìn)行計算的規(guī)律。但如果采用微機通信中XMODEM協(xié)議所使用的CRC查詢方式,則比直接CRC模2除法方式快4~10倍。查詢方法實施過程:首先用信息字節(jié)與累加器的高字節(jié)進(jìn)行異或,并將其結(jié)果作初始累加器為0的CRC;然后與原累加器的低字節(jié)再作一次異或。第一步只有256個樣式,可以構(gòu)造一個256個雙字節(jié)的查詢表,一步實現(xiàn)。這樣對每一字節(jié)只要作兩次操作就可完成。以下是具體步驟。
(1)構(gòu)造查詢表,運行直接模2除法CRC函數(shù)CRC(i,1021,0),用I從0~255代入,將結(jié)果按序排列可得到一個256個樣式的雙字節(jié)查詢表。該表只作一次,可以先用C語言微型機上作好,然后再移到單片機上,留作以后查詢使用。
(2)取一個雙字節(jié)累加器accum,賦初值0,將信息流的第一個字節(jié)賦給另一雙字節(jié)變量data(accum和data都是雙字節(jié)變量,以下步驟也是作雙字節(jié)運算)。
(3)將accum>>8(也即取原累加器accum的高字節(jié))的值與信息字data相異或,所得結(jié)果(是一個<256的值)查上述構(gòu)造好的查詢表,得到一個16位的暫存值。
(4)將accum<<8(即原累加器accum的低字節(jié)左移成高字節(jié),低位補0),與上一步得到的暫存值(16位的值)相異或,結(jié)果作為新的累加器值,賦值給accum。
(5)取信息流的下一字節(jié)賦給data,重復(fù)進(jìn)行第(3)步和第(4)步,直至所有的信息字節(jié)寢用完為止,最后累加器的值就是余數(shù)。
2 擴展?jié)h明碼
2.1 編碼方法
CRC校驗只能檢錯但不能糾錯。而1949年提出的漢明碼是一種能糾正單個錯誤的線性分組碼。其中,既是線性分組碼同時也是循環(huán)碼的(7,4)碼有兩種。其生成矩陣和校驗矩陣分列如下:

兩者使用效果等價。
漢明碼是糾正單個錯誤的完備碼,所有的接收碼都可對應(yīng)到一個信息(多一對應(yīng)),要么是正確信息,要么是發(fā)生單個錯誤的情形。當(dāng)有兩個錯誤時,會把它當(dāng)成另一個碼的單個錯誤加以糾正,導(dǎo)致誤碼。
擴展?jié)h明碼在此基礎(chǔ)上引入一個校驗和,即在編碼在時候增加第8位偶校驗位,構(gòu)成(8,4)線性分組碼,因而可以糾正一位錯誤同時檢出兩位錯誤。事件上,在發(fā)生錯誤時就是這個偶校驗位確定了是錯一位還是錯兩位。若錯一位則可以糾正,錯兩位就只能檢出但不能糾正。
編、譯碼均以擴展?jié)h明碼(8,4)線性分組碼為例。為了方便單片機的運算,實現(xiàn)快速編碼,可采用查詢法。因為信息是一個4位的矢量,記作C,共有16個可能值。為了構(gòu)成8位發(fā)射碼矢量,可以建立16個一字節(jié)的查詢作為8位的發(fā)送碼。以生成矩陣G1為例,用信息矢量C乘以成矩陣G1再加上一位偶校驗就得到了生成碼(發(fā)送碼)。查詢表為:





