|
分享關(guān)于modbus 51 例程,資料 工具:
Modbus兩種協(xié)議的編程方法:
1、LRC校驗
LRC域是一個包含一個8位二進制值的字節(jié)。LRC值由傳輸設(shè)備來計算并放到消息幀中,接收設(shè)備在接收消息的過程中計算LRC,并將它和接收到消息中LRC域中的值比較,如果兩值不等,說明有錯誤。
LRC校驗比較簡單,它在ASCII協(xié)議中使用,檢測了消息域中除開始的冒號及結(jié)束的回車換行號外的內(nèi)容。它僅僅是把每一個需要傳輸?shù)臄?shù)據(jù)按字節(jié)疊加后取反加1即可。下面是它對應(yīng)的代碼:
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,避開“開始標(biāo)記”冒號
{
//每兩個需要發(fā)送的ASCII碼轉(zhuǎn)化為一個十六進制數(shù)
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域是兩個字節(jié),包含一16位的二進制值。它由傳輸設(shè)備計算后加入到消息中。接收設(shè)備重新計算收到消息的CRC,并與接收到的CRC域中的值比較,如果兩值不同,則有誤。
CRC是先調(diào)入一值是全“1”的16位寄存器,然后調(diào)用一過程將消息中連續(xù)的8位字節(jié)各當(dāng)前寄存器中的值進行處理。僅每個字符中的8Bit數(shù)據(jù)對CRC有效,起始位和停止位以及奇偶校驗位均無效。
CRC產(chǎn)生過程中,每個8位字符都單獨和寄存器內(nèi)容相或(OR),結(jié)果向最低有效位方向移動,最高有效位以0填充。LSB被提取出來檢測,如果LSB為1,寄存器單獨和預(yù)置的值或一下,如果LSB為0,則不進行。整個過程要重復(fù)8次。在最后一位(第8位)完成后,下一個8位字節(jié)又單獨和寄存器的當(dāng)前值相或。最終寄存器中的值,是消息中所有的字節(jié)都執(zhí)行之后的CRC值。
CRC添加到消息中時,低字節(jié)先加入,然后高字節(jié)。下面是它對應(yīng)的代碼:
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協(xié)議的命令可以簡單的通過以下的步驟轉(zhuǎn)化為ASCII協(xié)議的命令:
1、 把命令的CRC校驗去掉,并且計算出LRC校驗取代。
2、 把生成的命令串的每一個字節(jié)轉(zhuǎn)化成對應(yīng)的兩個字節(jié)的ASCII碼,比如0x03轉(zhuǎn)化成0x30,0x33(0的ASCII碼和3的ASCII碼)。
3、 在命令的開頭加上起始標(biāo)記“:”,它的ASCII碼為0x3A。
4、 在命令的尾部加上結(jié)束標(biāo)記CR,LF(0xD,0xA),此處的CR,LF表示回車和換行的ASCII碼。
掌握兩種協(xié)議的編程方法,剩下的就是C語言的問題了。
悉雨辰寂
單片機源程序如下:
完整的Word格式文檔51黑下載地址:
Modbus兩種協(xié)議的編程方法.doc
(26 KB, 下載次數(shù): 160)
2018-3-27 18:56 上傳
點擊文件名下載附件
51單片機modbus例程.rar
(3.54 MB, 下載次數(shù): 293)
2018-3-27 18:56 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|