LRC CRC 縱向冗余碼校驗
2010-01-26 11:00:15| 分類: 電氣 | 標簽: |字號大中小 訂閱
1、LRC校驗
LRC域是一個包含一個8位二進制值的字節。LRC值由傳輸設備來計算並放到消息幀中,接收設備在接收消息的過程中計算LRC,並將它和接收到消息中LRC域中的值比較,如果兩值不等,說明有錯誤。 LRC校驗比較簡單,它在ASCII協議中使用,檢測了消息域中除開始的冒號及結束的回車換行號外的內容。
它僅僅是把每一個需要傳輸的數據按字節疊加后取反加1即可。下面是它對應的代碼:
BYTE GetCheckCode(const char * pSendBuf, int nEnd)//獲得校驗碼
{
BYTE byLrc = 0; char pBuf[4]; int nData = 0;
for(i=1; i<end; i+=2) //i初始為1,避開“開始標記”冒號
{
//每兩個需要發送的ASCII碼轉化為一個十六進制數
pBuf [0] = pSendBuf [i]; pBuf [1] = pSendBuf [i+1];
pBuf [2] = '\0';
sscanf(pBuf,"%x",& nData);
byLrc += nData;
}
byLrc = ~ byLrc;
byLrc ++; return byLrc;
}
2、CRC校驗
CRC域是兩個字節,包含一16位的二進制值。它由傳輸設備計算后加入到消息中。接收設備重新計算收
到消息的CRC,並與接收到的CRC域中的值比較,如果兩值不同,則有誤。
CRC是先調入一值是全“1”的16位寄存器,然后調用一過程將消息中連續的8位字節各當前寄存器中的值
進行處理。僅每個字符中的8Bit數據對CRC有效,起始位和停止位以及奇偶校驗位均無效。 CRC產生過程中,每個8位字符都單獨和寄存器內容相或(OR),結果向最低有效位方向移動,最高有效位以0填充。LSB被提取出來檢測,如果LSB為1,寄存器單獨和預置的值或一下,如果LSB為0,則不進行。整個過程要重復8次。在最后一位(第8位)完成后,下一個8位字節又單獨和寄存器的當前值
相或。最終寄存器中的值,是消息中所有的字節都執行之后的CRC值。 CRC添加到消息中時,低字節先加入,然后高字節。下面是它對應的代碼: WORD GetCheckCode(const char * pSendBuf, int nEnd)//獲得校驗碼
{
WORD wCrc = WORD(0xFFFF);
for(int i=0; i<nEnd; i++)
{
wCrc ^= WORD(BYTE(pSendBuf[i]));
for(int j=0; j<8; j++)
{ if(wCrc & 1)
{ wCrc >>= 1; wCrc ^= 0xA001;
} else { wCrc >>= 1;
} } } return wCrc;
}
對於一條RTU協議的命令可以簡單的通過以下的步驟轉化為ASCII協議的命令:
1、 把命令的CRC校驗去掉,並且計算出LRC校驗取代。
2、 把生成的命令串的每一個字節轉化成對應的兩個字節的ASCII碼,比如0x03轉化成0x30,0x33(0的
ASCII碼和3的ASCII碼)。
3、 在命令的開頭加上起始標記“:”,它的ASCII碼為0x3A。
4、 在命令的尾部加上結束標記CR,LF(0xD,0xA),此處的CR,LF表示回車和換行的ASCII碼。
掌握兩種協議的編程方法,剩下的就是C語言的問題了。
ddr123456 2009-02-18 13:44
請問哪位高手知道LRC校驗碼計算方法,程序如何寫(西門子S7-200與台達VFD-B變頻器通信)?
ljc2008
2009-02-18 15:08
2.LRC校驗碼
這是MODBUS通訊協議ASCII方式的校驗方法,LRC校驗碼不能直接用指令求出,但可編制程序自動算出,
算法:將參與校驗的數據求和,取其低8位的補碼為校驗碼
例:求數據 01H,03H,21H,02H,00H,02H 之求和校驗碼。
求和:01H + 03H + 21H + 02H + 00H + 02H = 29H 求補碼有二種方法: ① 求反加1 ② 用FFH相減 我們下面用求反加一來做
0 0 1 0 1 0 0 1
求反: 1 1 0 1 0 1 1 0
加 1: 0 0 0 0 0 0 0 1
1 1 0 1 0 1 1 1
D 7
LRC校驗碼為:D7H
