1. 程式人生 > >Modbus庫開發筆記之七:Modbus其他輔助功能開發

Modbus庫開發筆記之七:Modbus其他輔助功能開發

puts sin weak oid 數據格式 _weak 解析 但是 大端

前面開發了各種應用,但是卻一直沒有提到一個問題,你就是對具體的數據進行讀寫操作。對於Modbus來說標準的數據有4種:線圈數據(地址:0000x)、輸入狀態量數據(地址:1000x)、保持寄存器數據(地址:4000x)和輸入寄存器數據(地址:3000x)。我們通訊的目的就是為了對這些數據進行操作,可是我們前面的封裝中並沒有提到數據處理。事實上,也沒辦法考慮這一點,因為具體的應用數據千差萬別,是沒辦法封裝的。那我們怎麽解決這一問題呢?接下來我們將解決這一類問題。

1、數據處理函數的封裝

我們考慮到,不論是在RTU主站、RTU從站、TCP客戶端、還是在TCP服務器對數據的處理本質上是一樣的,只要具體應用的數據結構確定後處理方法也就確定了。鑒於此,我們采用的方法是定義弱化類型的函數。如下:

/*獲取想要讀取的Coil量的值*/

__weak void GetCoilStatus(uint16_t startAddress,uint16_t quantity,bool *statusList)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*獲取想要讀取的InputStatus量的值*/

__weak void GetInputStatus(uint16_t startAddress,uint16_t quantity,bool *statusValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*獲取想要讀取的保持寄存器的值*/

__weak void GetHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*獲取想要讀取的輸入寄存器的值*/

__weak void GetInputRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*設置單個線圈的值*/

__weak void SetSingleCoil(uint16_t coilAddress,bool coilValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*設置單個寄存器的值*/

__weak void SetSingleRegister(uint16_t registerAddress,uint16_t registerValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*設置多個線圈的值*/

__weak void SetMultipleCoil(uint16_t startAddress,uint16_t quantity,bool *statusValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*設置多個寄存器的值*/

__weak void SetMultipleRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

{

//如果需要Modbus TCP Server/RTU Slave應用中實現具體內容

}

/*更新讀回來的線圈狀態*/

__weak void UpdateCoilStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)

{

//在客戶端(主站)應用中實現

}

/*更新讀回來的輸入狀態值*/

__weak void UpdateInputStatus(uint16_t startAddress,uint16_t quantity,bool *stateValue)

{

//在客戶端(主站)應用中實現

}

/*更新讀回來的線圈狀態*/

__weak void UpdateHoldingRegister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

{

//在客戶端(主站)應用中實現

}

/*更新讀回來的線圈狀態*/

__weak void UpdateInputResgister(uint16_t startAddress,uint16_t quantity,uint16_t *registerValue)

{

//在客戶端(主站)應用中實現

}

在開發具體應用時,我們只需要在應用中實現對應的函數就可以使功能完整,至於具體的數據如何處理,就要看具體應用中的數據格式了。當然這些函數並非都需要實現,只需要根據自己的需要實現就可以了。

2、關於大小端的問題

提到數據通訊,有一個問題是沒有辦法回避的,那就是大小端的問題。對於Modbus協議來說,采用的是大端模式,就是低位地址存高位字節數據,高位地址存低位字節數據。

在進行多字節數據通訊時,大小端的問題就明顯了,比如一個浮點數在不同的系統中存儲的順序是有差別的,你讀上來或者寫下去的數據就會出現錯誤的解析。所以我們在處理數據報文時是必須考慮這一點的。

Modbus庫開發筆記之七:Modbus其他輔助功能開發