儀表網(wǎng)手機版
手機訪問更快捷
儀表網(wǎng)小程序
更多流量 更易傳播
公眾號:ybzhan
隨時掌握行業(yè)動態(tài)
掃碼關(guān)注視頻號
網(wǎng)絡(luò)課堂 行業(yè)直播
近期手頭有個項目,需要用mablab從一款四通道儀表上通過串口讀取有效的稱重數(shù)據(jù)。
首先,Modbus協(xié)議是一種常見的通信協(xié)議,常用于工業(yè)自動化。這里需要用到的是Modbus RTU模式,因為它通常通過串口進行通信,比如RS-485或RS-232。
從用戶的問題來看,有幾個關(guān)鍵點:
1、使用MATLAB的串口接口。
2、儀表的從機地址是1。
3、讀取保持寄存器,從11號開始,讀8個寄存器。
4、每兩個寄存器組成一個32位有符號整數(shù),然后就返回四個這樣的數(shù)值。
首先,我需要知道如何在MATLAB中使用串口。MATLAB有一個Instrument Control Toolbox,里面有serialport函數(shù)可以用來配置和操作串口設(shè)備。
接下來是Modbus協(xié)議的具體實現(xiàn)部分。因為MATLAB可能沒有內(nèi)置的Modbus庫,所以可能需要自己構(gòu)造Modbus RTU幀。這包括:
·從機地址:1個字節(jié)。
·函數(shù)碼:讀保持寄存器(0x03)。
·起始地址:兩個字節(jié),這里是從11號開始。
·寄存器數(shù)量:一個字節(jié),這里是8個。
·CRC校驗。
所以Modbus RTU幀的結(jié)構(gòu)大致是:
[設(shè)備地址][功能碼][起始地址高][起始地址低][寄存器數(shù)量][數(shù)據(jù)…][CRC]
在代碼中,我需要構(gòu)造這個幀,然后通過串口發(fā)送出去,并等待儀表的響應(yīng)。收到的數(shù)據(jù)需要進行解析。
接下來考慮如何處理接收到的數(shù)據(jù)。Modbus RTU的響應(yīng)結(jié)構(gòu)是:
·設(shè)備地址(1字節(jié))
·功能碼(1字節(jié))
·數(shù)據(jù)部分(2個字節(jié)每個寄存器,共8*2=16字節(jié))
·CRC校驗(2字節(jié))
所以數(shù)據(jù)部分會被分割成4組,每兩個字節(jié)組成一個32位整數(shù)。因為用戶要求的是有符號的整數(shù),所以在轉(zhuǎn)換時需要處理為int32類型。
我還需要注意字節(jié)順序的問題。通常情況下,Modbus的數(shù)據(jù)傳輸是使用大端字節(jié)序,即高位在前。但在MATLAB中處理的時候,可能需要調(diào)整字節(jié)順序。
接下來我們列出具體的步驟:
1、配置串口:正確的波特率、數(shù)據(jù)位、停止位等參數(shù)。假設(shè)儀表的波特率為9600,8數(shù)據(jù)位,無奇偶校驗,1停止位。
2、打開串口連接。
3、構(gòu)造Modbus RTU讀取請求幀:
a. 設(shè)備地址:1
b. 功能碼:0x03(十進制51)
c. 起始地址:高字節(jié)和低字節(jié)。11的十六進制是0x0B,所以高位是0x00,低位是0x0B。
d. 寄存器數(shù)量:8
4、計算CRC校驗。這個部分可能需要查找Modbus RTU CRC算法,通常是計算前三個字節(jié)(設(shè)備地址、功能碼和數(shù)據(jù)字段)的多項式,得到兩個字節(jié)的校驗值。
5、發(fā)送請求幀到串口。
6、等待響應(yīng),并讀取返回的數(shù)據(jù)。
7、解析響應(yīng)幀:
a. 檢查設(shè)備地址和功能碼是否正確。
b. 提取數(shù)據(jù)部分。
8、將16個字節(jié)分成4組,每組兩個字節(jié)構(gòu)成一個32位整數(shù)。需要注意的是,這可能涉及到將兩個字節(jié)合并成一個雙字節(jié)值,并轉(zhuǎn)換為有符號整數(shù)。
在構(gòu)造請求幀的時候,我需要計算CRC校驗。我記得Modbus RTU的CRC是基于0xFFFF的多項式,使用的是16位的循環(huán)冗余校驗碼。所以,需要寫一個函數(shù)來計算這個CRC。
另外,在讀取串口數(shù)據(jù)時,可能會遇到超時的問題。所以代碼中需要設(shè)置適當(dāng)?shù)牡却龝r間,并且處理可能的錯誤情況,比如沒有收到足夠的數(shù)據(jù)或者CRC不匹配的情況。
接下來是具體實現(xiàn):
1、配置串口:
使用serialport對象,設(shè)置波特率、字節(jié)大小等參數(shù)。
2、構(gòu)造請求幀:
設(shè)備地址:1(一個字節(jié))
功能碼:3(十進制,對應(yīng)0x03)
起始地址:高位是0x00,低位是0x0B
寄存器數(shù)量:8
數(shù)據(jù)部分暫時為空,因為請求幀的數(shù)據(jù)字段包含起始地址和寄存器數(shù)量,所以請求的數(shù)據(jù)字段為[0x00, 0x0B, 0x08]。然后計算CRC校驗。
構(gòu)造完整的請求幀應(yīng)該是:
[1 (設(shè)備地址), 3 (功能碼), 0x00, 0x0B, 0x08, CRC_high, CRC_low]
這里需要注意的是,數(shù)據(jù)部分在請求中是包含起始地址和寄存器數(shù)量的,所以數(shù)據(jù)字段是三個字節(jié):起始高、起始低、寄存器數(shù)。那計算CRC的時候,需要包括這些三個字節(jié)嗎?或者是不是只計算前兩個字節(jié)?
不,Modbus RTU中的數(shù)據(jù)部分在請求中包含的是起始地址和寄存器數(shù)量,因此數(shù)據(jù)字段的長度是2(起始地址)+1(寄存器數(shù)量)=3個字節(jié)。所以在構(gòu)造請求時,整個幀的數(shù)據(jù)字段包括這三個字節(jié)。那計算CRC的時候,是否只對前三個字節(jié)進行校驗?
不,實際上Modbus RTU的CRC是針對設(shè)備地址、功能碼和數(shù)據(jù)部分的所有字節(jié)進行計算的。所以,在本例中,數(shù)據(jù)部分有3個字節(jié):起始高(0x00)、起始低(0x0B)和寄存器數(shù)(0x08)。因此,總共有1(設(shè)備地址) + 1(功能碼) +3(數(shù)據(jù)部分)=5個字節(jié)用于計算CRC。
然后,我需要編寫一個函數(shù)來計算這五個字節(jié)的多項式生成校驗碼。這可能有點復(fù)雜,但網(wǎng)上可以找到Modbus CRC-16算法的實現(xiàn)方式。
另外,在解析響應(yīng)時,收到的數(shù)據(jù)應(yīng)該包括設(shè)備地址、功能碼、數(shù)據(jù)部分和CRC。首先檢查設(shè)備地址是否為1,功能碼是否正確,然后計算接收到的數(shù)據(jù)部分是否符合預(yù)期,并驗證CRC是否正確。
關(guān)于轉(zhuǎn)換字節(jié)到32位整數(shù)的部分,我需要將每兩個連續(xù)的字節(jié)合并成一個雙字節(jié)值。需要注意的是,MATLAB中的處理方式可能會影響符號的問題,因為數(shù)據(jù)是以有符號整數(shù)形式返回。
舉個例子,假設(shè)收到的數(shù)據(jù)是字節(jié)1和字節(jié)2,那么這個數(shù)值如何轉(zhuǎn)換?在Modbus中,通常是將高字節(jié)放在前面(大端),所以字節(jié)作為高位,第二個字節(jié)作為低位。然后將它們組合成一個16位的無符號整數(shù),再轉(zhuǎn)換為有符號整數(shù)。
比如,如果有兩個字節(jié):0x12和0xAB,那么合并的結(jié)果是 0x12AB,將其視為有符號整數(shù),應(yīng)該是43957。
但是在MATLAB中,這可能需要一些處理。因為字節(jié)的順序會影響結(jié)果,所以可能需要將它們轉(zhuǎn)換為一個雙字節(jié)值,并考慮是否有符號的問題。
另外,在解析數(shù)據(jù)時,我還需要確保數(shù)據(jù)部分確實返回了8個寄存器的數(shù)據(jù),也就是16個字節(jié),這樣可以得到4組兩個字節(jié),最終組成四個整數(shù)
相關(guān)產(chǎn)品
免責(zé)聲明
客服熱線: 18758282240(同微信)
加盟熱線: 18758282240(同微信)
媒體合作: 0571-87759945
投訴熱線: 0571-87759942

下載儀表站APP

Ybzhan手機版

Ybzhan公眾號

Ybzhan小程序