|
通信協(xié)議里有CRC校驗(yàn)碼,計(jì)算從報(bào)文的起始字節(jié)到報(bào)文內(nèi)容最后一個(gè)字節(jié)的crc16的值。 舉個(gè)例子: 遠(yuǎn)程控制命令集 5B 20 00 0A 00 01 0A 01 FE 00 01 00 AB 89 CRC校驗(yàn)碼為:AB 89 一、RTU 檢查碼(CRC)計(jì)算器 第一種: 參看:RTU 檢查碼(CRC)計(jì)算器 大小端轉(zhuǎn)換后,CRC檢查碼為:AB 89 說明,這個(gè)計(jì)算器還是可以用的。 第二種: 參看:On-line CRC calculation and free library 二、運(yùn)算規(guī)則 RTU檢查碼(CRC)計(jì)算,運(yùn)算規(guī)則如下: 步驟1:令16位暫存器(CRC暫存器)= 0xFFFF。 步驟2:異或第一個(gè)8位字節(jié)的消息指令與低位元16位CRC暫存器,做異或?qū)⒔Y(jié)果存入CRC暫存器內(nèi)。 步驟3:右移一位CRC暫存器,將0填入高位元處。 步驟4:檢查右移的值,如果是0將步驟3的新值存入CRC暫存器內(nèi),否則異或0xA001與CRC暫存器,將結(jié)果存入CRC暫存器內(nèi)。 步驟5:重復(fù)步驟3〜步驟4,將8位全部運(yùn)算完成。 步驟6:重復(fù)步驟2〜步驟5,取下一個(gè)8位的消息指令,直到所有消息指令運(yùn)算完成。最后,得到的CRC緩存器的值,即CRC的檢查碼。值得注意的是CRC的檢查碼必須交換放置于訊息指令的檢查碼中。 三、相關(guān)代碼 擴(kuò)展參看:C語(yǔ)言再學(xué)習(xí)– 位操作 int16_t factory_crc16 ( uint8_t *bufData,uint16_t buflen) { uint16_t TCPCRC = 0xffff; uint16_t POLYNOMIAL = 0xa001; uint8_t i, j; for (i = 0; i < buflen; i++) { TCPCRC ^= bufData; for (j = 0; j < 8; j++) { if ((TCPCRC & 0x0001) != 0) { TCPCRC >>= 1; TCPCRC ^= POLYNOMIAL; } else { TCPCRC >>= 1; } } } return TCPCRC; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 四、CRC校驗(yàn)原理及步驟 參看:CRC校驗(yàn)原理及步驟 1、什么是CRC校驗(yàn)? CRC即循環(huán)冗余校驗(yàn)碼:是數(shù)據(jù)通信領(lǐng)域中最常用的一種查錯(cuò)校驗(yàn)碼,其特征是信息字段和校驗(yàn)字段的長(zhǎng)度可以任意選定。循環(huán)冗余檢查(CRC)是一種數(shù)據(jù)傳輸檢錯(cuò)功能,對(duì)數(shù)據(jù)進(jìn)行多項(xiàng)式計(jì)算,并將得到的結(jié)果附在幀的后面,接收設(shè)備也執(zhí)行類似的算法,以保證數(shù)據(jù)傳輸?shù)恼_性和完整性。 2、CRC校驗(yàn)原理: 其根本思想就是先在要發(fā)送的幀后面附加一個(gè)數(shù)(這個(gè)就是用來校驗(yàn)的校驗(yàn)碼,但要注意,這里的數(shù)也是二進(jìn)制序列的,下同),生成一個(gè)新幀發(fā)送給接收端。當(dāng)然,這個(gè)附加的數(shù)不是隨意的,它要使所生成的新幀能與發(fā)送端和接收端共同選定的某個(gè)特定數(shù)整除(注意,這里不是直接采用二進(jìn)制除法,而是采用一種稱之為模2除法。到達(dá)接收端后,再把接收到的新幀除以(同樣采用“模2除法”)這個(gè)選定的除數(shù)。因?yàn)樵诎l(fā)送端發(fā)送數(shù)據(jù)幀之前就已通過附加一個(gè)數(shù),做了“去余”處理(也就已經(jīng)能整除了),所以結(jié)果應(yīng)該是沒有余數(shù)。如果有余數(shù),則表明該幀在傳輸過程中出現(xiàn)了差錯(cuò)。 模2除法: 模2除法與算術(shù)除法類似,但每一位除的結(jié)果不影響其它位,即不向上一位借位,所以實(shí)際上就是異或。在循環(huán)冗余校驗(yàn)碼(CRC)的計(jì)算中有應(yīng)用到模2除法。 例: 3、CRC校驗(yàn)步驟: CRC校驗(yàn)中有兩個(gè)關(guān)鍵點(diǎn),一是預(yù)先確定一個(gè)發(fā)送送端和接收端都用來作為除數(shù)的二進(jìn)制比特串(或多項(xiàng)式),可以隨機(jī)選擇,也可以使用國(guó)際標(biāo)準(zhǔn),但是最高位和最低位必須為1;二是把原始幀與上面計(jì)算出的除數(shù)進(jìn)行模2除法運(yùn)算,計(jì)算出CRC碼。 4、具體步驟: 選擇合適的除數(shù) 看選定除數(shù)的二進(jìn)制位數(shù),然后再要發(fā)送的數(shù)據(jù)幀上面加上這個(gè)位數(shù)-1位的0,然后用新生成的幀以模2除法的方式除上面的除數(shù),得到的余數(shù)就是該幀的CRC校驗(yàn)碼。注意,余數(shù)的位數(shù)一定只比除數(shù)位數(shù)少一位,也就是CRC校驗(yàn)碼位數(shù)比除數(shù)位數(shù)少一位,如果前面位是0也不能省略。 將計(jì)算出來的CRC校驗(yàn)碼附加在原數(shù)據(jù)幀后面,構(gòu)建成一個(gè)新的數(shù)據(jù)幀進(jìn)行發(fā)送;最后接收端在以模2除法方式除以前面選擇的除數(shù),如果沒有余數(shù),則說明數(shù)據(jù)幀在傳輸?shù)倪^程中沒有出錯(cuò)。 5、CRC校驗(yàn)碼計(jì)算示例: 現(xiàn)假設(shè)選擇的CRC生成多項(xiàng)式為G(X) = X4 + X3 + 1,要求出二進(jìn)制序列10110011的CRC校驗(yàn)碼。下面是具體的計(jì)算過程: ①將多項(xiàng)式轉(zhuǎn)化為二進(jìn)制序列,由G(X) = X4 + X3 + 1可知二進(jìn)制一種有五位,第4位、第三位和第零位分別為1,則序列為11001 ②多項(xiàng)式的位數(shù)位5,則在數(shù)據(jù)幀的后面加上5-1位0,數(shù)據(jù)幀變?yōu)?/font>101100110000,然后使用模2除法除以除數(shù)11001,得到余數(shù)。 ③將計(jì)算出來的CRC校驗(yàn)碼添加在原始幀的后面,真正的數(shù)據(jù)幀為101100110100,再把這個(gè)數(shù)據(jù)幀發(fā)送到接收端。 ④接收端收到數(shù)據(jù)幀后,用上面選定的除數(shù),用模2除法除去,驗(yàn)證余數(shù)是否為0,如果為0,則說明數(shù)據(jù)幀沒有出錯(cuò)。 --------------------- 作者:聚優(yōu)致成 來源:CSDN 原文:https://blog.csdn.net/qq_29350001/article/details/79518638 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
|