新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 串口通信數(shù)據(jù)校驗(yàn)問題

串口通信數(shù)據(jù)校驗(yàn)問題

作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
Modbus協(xié)議

Modbus協(xié)議最初由Modicon公司 開發(fā)出來,在1979年末該公司成為施耐德自動化(Schneider Automation)部門的一部分,現(xiàn)在Modbus已經(jīng)是工業(yè)領(lǐng)域全球最流行的協(xié)議。此協(xié)議支持傳統(tǒng)的RS-232、RS-422、RS-485以太網(wǎng)設(shè)備。許多工業(yè)設(shè)備,包括PLC,DCS,智能儀表等都在使用Modbus協(xié)議作為他們之間的通訊標(biāo)準(zhǔn)。有了它,不同廠商生產(chǎn)的控制設(shè)備可以連成工業(yè)網(wǎng)絡(luò),進(jìn)行集中監(jiān)控。

本文引用地址:http://m.butianyuan.cn/article/201611/315957.htm

當(dāng)在網(wǎng)絡(luò)上通信時(shí),Modbus協(xié)議決定了每個控制器須要知道它們的設(shè)備地址,識別按地址發(fā)來的消 息,決定要產(chǎn)生何種行動。如果需要回應(yīng),控制器將生成應(yīng)答并使用Modbus協(xié)議發(fā)送給詢問方。

Modbus協(xié)議包括ASCII、RTU、TCP等,并沒有規(guī)定物理層。此協(xié)議定義了控制器能夠認(rèn)識 和使用的消息結(jié)構(gòu),而不管它們是經(jīng)過何種網(wǎng)絡(luò)進(jìn)行通信的。標(biāo)準(zhǔn)的Modicon控制器使用RS232C實(shí)現(xiàn)串行的Modbus。Modbus的ASCII、RTU協(xié)議規(guī)定了消息、數(shù)據(jù)的結(jié)構(gòu)、命令和就答的方式,數(shù)據(jù)通訊采用Maser/Slave方式,Master端發(fā)出數(shù)據(jù)請求消息,Slave端接收到正確消息后就可以發(fā)送數(shù)據(jù)到Master端以響應(yīng)請求;Master端也可以直接發(fā)消息修改Slave端的數(shù)據(jù),實(shí)現(xiàn)雙向讀寫。

Modbus協(xié)議需要對數(shù)據(jù)進(jìn)行校驗(yàn),串行協(xié)議中除有奇偶校驗(yàn)外,ASCII模式采用LRC校驗(yàn),RTU模 式采用16位CRC校驗(yàn),但TCP模式?jīng)]有額外規(guī)定校驗(yàn),因?yàn)門CP協(xié)議是一個面向連接的可靠協(xié)議。另外,Modbus采用主從方式定時(shí)收發(fā)數(shù)據(jù),在實(shí)際使用中如果 某Slave站點(diǎn)斷開后(如故障 或關(guān)機(jī)),Master端可以診 斷出來,而當(dāng)故障修復(fù)后,網(wǎng)絡(luò)又可自動接通。因此,Modbus協(xié)議的可靠性較好。

下面我來簡單的給大家介紹一下,對于Modbus的ASCII、RTU和TCP協(xié)議來說,其中TCP和RTU協(xié)議非常類似,我們只要把RTU協(xié)議的兩個字節(jié)的校驗(yàn)碼去掉,然后在RTU協(xié)議的開始加上5個0和一個6并通過TCP/IP網(wǎng)絡(luò)協(xié)議發(fā)送出去即可。所以在這里我僅介紹一下Modbus的ASCII和RTU協(xié)議。

下表是ASCII協(xié)議和RTU協(xié)議進(jìn)行的比較:

協(xié)議

開始標(biāo)記

結(jié)束標(biāo)記

校驗(yàn)

傳輸效率

程序處理

ASCII

:(冒號)

CR,LF

LRC

直觀,簡單,易調(diào)試

RTU

CRC

不直觀,稍復(fù)雜

通過比較可以看到,ASCII協(xié)議和RTU協(xié)議相比擁有開始和結(jié)束標(biāo)記,因此在進(jìn)行程序處理時(shí)能更加方便,而且由于傳輸?shù)亩际强梢姷腁SCII字符,所以進(jìn)行調(diào)試時(shí)就更加的直觀,另外它的LRC校驗(yàn)也比較容易。但是因?yàn)樗鼈鬏數(shù)亩际强梢姷腁SCII字符,RTU傳輸?shù)臄?shù)據(jù)每一個字節(jié)ASCII都 要用兩個字節(jié)來傳輸,比如RTU傳輸一個十六進(jìn)制數(shù)0xF9,ASCII就需要傳輸’F’’9’的ASCII碼0x39和0x46兩個字節(jié),這樣它的傳輸?shù)男示捅容^低。所以一般來說,如果所需要傳 輸?shù)臄?shù)據(jù)量較小可以考慮使用ASCII協(xié)議,如果所 需傳輸?shù)臄?shù)據(jù)量比較大,最好能使用RTU協(xié)議。

下面對兩種協(xié)議的校驗(yàn)進(jìn)行一下介紹。

1、LRC校驗(yàn)

LRC域是一個包含一個8位二進(jìn)制值的 字節(jié)。LRC值由傳輸設(shè)備來計(jì)算并放到消息幀中,接 收設(shè)備在接收消息的過程中計(jì)算LRC,并將它和接收 到消息中LRC域中的值比較,如果兩值不等,說明有 錯誤。

LRC校驗(yàn)比較簡單,它在ASCII協(xié)議中使 用,檢測了消息域中除開始的冒號及結(jié)束的回車換行號外的內(nèi)容。它僅僅是把每一個需要傳輸?shù)臄?shù)據(jù)按字節(jié)疊加后取反加1即可。下面是它的VC代碼:

BYTE GetCheckCode(const char * pSendBuf, int nEnd)//獲得校驗(yàn)碼

{

BYTE byLrc = 0;

char pBuf[4];

int nData = 0;

for(i=1; i

{

// 每兩個需要發(fā)送的ASCII碼轉(zhuǎn)化為一個十六進(jìn)制數(shù)

pBuf [0] = pSendBuf [i];

pBuf [1] = pSendBuf [i+1];

pBuf [2] =