Modbus Ascii Rtu 區別與聯絡

2021-07-10 09:10:15 字數 3364 閱讀 7944

modbus-ascii協議和rtu協議的比較

通過比較可以看到,ascii協議和rtu協議相比擁有開始和結束標記,因此在進行程式處理時能更加方便,而且由於傳輸的都是可見的ascii字元,所以進行除錯時就更加的直觀,另外它的lrc校驗也比較容易。但是因為它傳輸的都是可見的ascii字元,rtu傳輸的資料每乙個位元組ascii都要用兩個位元組來傳輸,比如rtu傳輸乙個十六進製制數0xf9,ascii就需要傳輸』f』』9』的ascii碼0x39和0x46兩個位元組,這樣它的傳輸的效率就比較低。所以一般來說,如果所需要傳輸的資料量較小可以考慮使用ascii協議,如果所需傳輸的資料量比較大,最好能使用rtu協議。

下面對兩種協議的校驗進行一下介紹。

1、lrc校驗

lrc域是乙個包含乙個8位二進位制值的位元組。lrc值由傳輸裝置來計算並放到訊息幀中,接收裝置在接收訊息的過程中計算lrc,並將它和接收到訊息中lrc域中的值比較,如果兩值不等,說明有錯誤。

lrc校驗比較簡單,它在ascii協議中使用,檢測了訊息域中除開始的冒號及結束的回車換行號外的內容。它僅僅是把每乙個需要傳輸的資料按位元組疊加後取反加1即可。下面是它的vc**:

byte getcheckcode(const char * psendbuf, int nend)//獲得校驗碼

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新增到訊息中時,低位元組先加入,然後高位元組。下面是它的vc**:

word getcheckcode(const char * psendbuf, int nend)//獲得校驗碼

else}}

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碼。

所以以下我們僅介紹rtu協議即可,對應的ascii協議可以使用以上的步驟來

生成。modbus 是modicon公司最先倡導的一種的通訊規約,modbus可在程式設計控制器之間可相互通訊,也可與不

。一般來說,通訊資料量少而且主要是文字的通訊則採用modbus ascii規約,通訊資料資料量大而且是

備傳送乙個資訊,則可從一台從機裝置返回乙個響應,類似,當一台控制器接受資訊時,它就組織乙個

從機裝置的響應資訊,並返回至原傳送資訊的控制器。

查詢響應週期:

以下我介紹的是modbus rtu規約格式:

一 格式:

查詢命令格式:

這裡我說明一下:

根據我現場除錯發現,每個暫存器值對應二個位元組資料。上面命令格式「讀取資料個數」應該是指讀取

暫存器個數,因為值是存放在暫存器的,狀態量通常用0,1表示。讀乙個就夠了。如果是功能碼03,04返

回的值有int,float型,剛需要讀取2個暫存器,2×2=4就剛好。

正常回應格式:

異常應答返回

modbus異常響應的異常碼值表示如下: 

異常碼 

描述 響應解釋 

01 無效功  

變送器不允許執行收到的功能 

02 無效位址  

資料欄中的位址是不允許的 

03  

無效資料  

資料欄中的資料是不允許的 

06  

忙  收到的訊息沒錯,但從機正在執行乙個長的程式命令  .

二功能碼解釋:

從機會根據收到的功能碼執行相應動作之後返回響應資料。modbus的功能碼如下:

根據我現場除錯後,我才能比較正確的理解命令格式:其01,02功能碼讀取的響應資訊是位元值位,03

,04功能是int,float..等值,要最後取得這些值還得處理。比如是float型的,是由4個byte的資料構成

的,而要得到這個float型的正確值,你得根據所在的系統大端或小端方式進行轉換才正確。

例如:例一:

我要查詢空調現在的開關機狀態,要知道的是:空調裝置位址(0x01),開關機是狀態位(0表示關,1表

示開),所以用功能碼01或02.讀取暫存器位址(假設是1013),讀取的資料位數01(1位就可以了)。以

上這個值廠家都會有說明的,就像我上面提到的excel表類似一樣。

傳送的查詢命令:(都是十六進製制)

01 02  03  f5  00  01  ― ―  (後面的――表示crc值,自己計算。)

假設空調是處於開機狀態,能正確執行的響應就是如下:

01  02  01  01 

――例二:

我要讀取當前空調的顯示溫度(float值型)。

功能碼03或04.暫存器位址從2340-2341(2個暫存器就對應2*2=4個位元組)。

傳送查詢命令:

01  04  09  7e 

00  02  ――

假設空調溫度是21攝氏度。能正確執行的響應就是如下:

01  04  04  41  a8  00  00  ――

把4個資料值:41 a8 00 00  按照小端方式(vc下)倒序一下就可以強行用float型讀取就可以了得到值

21了。

堆區 棧區 靜態區 常量區還有???

常見的儲存區域可分為 由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個new就要對應乙個delete。如果程式設計師沒有釋放掉,程式會一直占用記憶體,導致記憶體洩漏...

c 棧區 堆區 常量區

c 中棧區 堆區 常量區 由一道面試題目而學習 2009 04 28 21 01 include void main 對應的彙編 10 a c 1 00401067 8a 4d f1 mov cl,byte ptr ebp 0fh 0040106a 88 4d fc mov byte ptr ebp...

記憶體的使用 棧區 堆區 靜態區 唯讀區

記憶體的使用感覺好亂啊,需要整理一下!於是參考c primer與網上資源,整理如下 一 綜述 記憶體中的棧區分配的是區域性變數和函式的引數值的空間,棧的生長方向是從高往低的 堆區是向上增長的用於分配程式設計師申請的記憶體空間 比如new 申請的動態記憶體 注意它與資料結構中的堆是兩回事,分配方式倒是...