與Modbus RTU在串行鍊路上分為Slave和Master一樣,Modbus ASCII也分為Slave和Master,這一節我們就來開發Slave。對于Modbus ASCII從站來說,需要實作的功能其實與Modbus RTU的Slave是一樣的。其操作過程也是一樣的。首先接收到主站的通路指令,對該指令封包進行解析,這裡我們也隻是實作前面提到的8種功能碼。其次我們根據解析的結果進行對應的操作,具體的軟體通路結構如下:

從上圖中不難發現實際是3步:
第1步、接到指令後先解析。解析的方式與前面幾節中的類式。
第2步、根據解析結果進行操作。包括更具指令修改或者擷取變量的值。
第3步、生成響應并傳回給主機。
1、解析主機指令
從機在接收到主機的指令封包後,對其進行解析,我們暫且支援上圖所示的8種功能碼。
/*解析接收到的資訊,并傳回合成的回複資訊和資訊的位元組長度,通過回調函數*/
uint16_t ParsingAsciiMasterAccessCommand(uint8_t *receivedMessage, uint8_t *respondBytes, uint16_t rxLength, uint8_t StationAddress)
該函數接收接受到的封包,并生成響應資訊封包,傳回值是響應封包的長度。在開發應用是将接收到的封包發送個該函數,并将生成的響應資訊傳回個用戶端就可以了。
2、結果操作
解析之後無論是讀指令還是寫指令都需要進行相應的操作。我們根據不同的功能碼封裝不同的操作:
/*處理讀線圈狀态指令*/
static uint16_t HandleReadCoilStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理讀輸入狀态指令*/
static uint16_t HandleReadInputStatusCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理讀保持寄存器指令*/
static uint16_t HandleReadHoldingRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理讀輸入寄存器指令*/
static uint16_t HandleReadInputRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理寫單個線圈指令*/
static uint16_t HandleWriteSingleCoilCommand(uint16_t coilAddress,uint16_t coilValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理寫單個寄存器指令*/
static uint16_t HandleWriteSingleRegisterCommand(uint16_t registerAddress,uint16_t registerValue,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理寫多個線圈狀态*/
static uint16_t HandleWriteMultipleCoilCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
/*處理寫多個寄存器狀态*/
static uint16_t HandleWriteMultipleRegisterCommand(uint16_t startAddress,uint16_t quantity,uint8_t *receivedMessage,uint8_t *respondBytes)
同樣我們也是定義一個函數指針數組來實作這8個函數的調用:
uint16_t (*HandleAsciiMasterCommand [])(uint16_t,uint16_t,uint8_t *,uint8_t *)={HandleReadCoilStatusCommand,
HandleReadInputStatusCommand,
HandleReadHoldingRegisterCommand,
HandleReadInputRegisterCommand,
HandleWriteSingleCoilCommand,
HandleWriteSingleRegisterCommand,
HandleWriteMultipleCoilCommand,
HandleWriteMultipleRegisterCommand};
3、生成從機響應
處理完還需要生成從機的相應資訊,無論是讀操作指令還是寫操作指令,我們均在對應的功能碼處理時生成響應封包。這麼一來在開發應用時,隻需要調用解析函資料可以實作全部的功能了。
源代碼可上Github下載下傳:https://github.com/foxclever/Modbus
歡迎關注:
如果您希望更友善且及時的閱讀相關文章,關注我的微信公衆号【木南創智】