c语言rtu crc16,Modbus-RTU-crc16校验方法C语言实现
為確保消息數據的完整性,除了驗證消息CRC之外,建議實現檢查串行端口(UART)成幀錯誤的代碼。如果接收消息中的CRC與接收設備計算的CRC不匹配,則應忽略該消息。下面的C語言代碼片段顯示了如何使用逐位移位和異或運算來計算Modbus消息CRC。使用消息幀中的每個字節計算CRC,除了包含CRC本身的最后兩個字節。
一、CRC16校驗碼的使用
現選擇最常用的CRC-16校驗,說明它的使用方法。
根據Modbus協議,常規485通訊的信息發送形式如下:
地址 功能碼 數據信息 校驗碼
1byte 1byte nbyte 2byte
CRC校驗是前面幾段數據內容的校驗值,為一個16位數據,發送時,
!!!!低8位在前,高8為最后。這點很重要!!!!
例如:信息字段代碼為: 1011001,校驗字段為:1010。
發送方:發出的傳輸字段為: 1 0 1 1 0 0 1 1 0 10
信息字段 校驗字段
接收方:使用相同的計算方法計算出信息字段的校驗碼,對比接收到的實際校驗碼,如果相等及信息正確,不相等則信息錯誤;或者將接受到的所有信息除多項式,如果能夠除盡,則信息正確。
二、CRC16校驗碼計算方法
常用查表法和計算法。計算方法一般都是:
(1)、預置1個16位的寄存器值0xFFFF,稱此寄存器為CRC寄存器;
(2)、把第一個8位二進制數據(既通訊信息幀的第一個字節)與16位的CRC寄存器的低
8位相異或,把結果放于CRC寄存器,高八位數據不變;
(3)、把CRC寄存器的內容右移一位(朝高位)用0填補最高位,并檢查右移后的移出位;
(4)、如果移出位為0:重復第3步(再次右移一位);如果移出位為1,CRC寄存器與一多
項式(A001)進行異或;
(5)、重復步驟3和4,直到右移8次,這樣整個8位數據全部進行了處理;
(6)、重復步驟2到步驟5,進行通訊信息幀下一個字節的處理;
(7)、將該通訊信息幀所有字節按上述步驟計算完成后,得到的16位CRC寄存器的高、低
字節進行交換;
(8)、最后得到的CRC寄存器內容即為:CRC碼。
以上計算步驟中的多項式A001是8005按位顛倒后的結果。
少了一個高低字節交換的語句!!!
-------------------------------------------------
unsigned int CRC16;
#define SEED0xFFFF//initialization for CRC16
#define GP0xA001//generating polynomial
//for standard CRC16
//(remainder of division)
//to start a new CRC, set CRC16 = SEED
//then for each byte call Calc_CRC(byte, &CRC16);
//CRC16 will contain the result
//(if you calculate all of the incoming data
//INCLUDING the CRC, the result should be 0x0000
//and if you are sending the CRC be sure to
//send the bytes in the correct order)
voidCalc_CRC(unsigned byte b,unsigned int*CRC)
{
BOOL carry;
int i;
CRC[]^=b&0xFF;
for(i=;i
{
carry=CRC[]&0x0001;
CRC[]>>=1;
if(carry)
CRC[]^=GP;
}
}
-------------------------------------------------
這個代碼是正確的!!!!
unsigned intCRC16_2(unsigned char*buf,int len)
{
unsigned int crc=0xFFFF;
for(int pos=;pos
{
crc^=(unsigned int)buf[pos];// XOR byte into least sig. byte of crc
for(int i=8;i!=;i--)// Loop over each bit
{
if((crc&0x0001)!=)// If the LSB is set
{
crc>>=1;// Shift right and XOR 0xA001
crc^=0xA001;
}
else// Else LSB is not set
{
crc>>=1;// Just shift right
}
}
}
//高低字節轉換
crc=((crc&0x00ff)8);
returncrc;
}?????????????????
本文參與騰訊云自媒體分享計劃,歡迎正在閱讀的你也加入,一起分享。
總結
以上是生活随笔為你收集整理的c语言rtu crc16,Modbus-RTU-crc16校验方法C语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xlsx是什么文件的格式(Excel无法
- 下一篇: 动画-animation_html/cs