Modbus串行通信


一、Modbus通信協議簡介

1. Modbus協議      

       Modbus 是一個請求/應答協議,並且提供功能碼規定的服務。Modbu協議是 OSI 模型第 7 層上的應用層報文傳輸協議。

       MODBUS協議支持傳統的RS-232、RS-422、RS-485和以太網設備。

Modbus 協議定義了一個與基礎通信層無關的簡單協議數據單元(PDU)。特定總線或網絡上的 Modbus 協議映射能夠在應用數據單元(ADU)上引入一些附加域。

      Modbus的數據包格式為:

2. 串行Modbus協議

       在物理層,Modbus 串行鏈路系統可以使用不同的物理接口(RS485、RS232)。支持RS485兩線制與四線制接口,當只需要短距離的點到點通信時,RS232 串行接口也可以使用。

串行通信棧對應與OSI七層協議的關系:

2.1 Modbus主站/從站協議

         Modbus 串行鏈路協議是一個主-從協議。 在同一時刻,只有一個主節點連接於總線,一個或多個子節點 (最大編號為 247 ) 連接於同一個串行總線。子節點之間從不會互相通信。

主節點有兩種方式與子節點發出請求:

      (1) 單播模式 :點對點發送,主節點發送請求,子節點回應。

      (2) 廣播模式 :廣播發送,主節點發送,子節點不回應。

Modbus串行鏈路PDU構成如下:

 

二、 Modbus( 串行)開源庫代碼學習

1. Modbus主節點與子節點的狀態

1.1主節點狀態

 

1.2 子節點狀態

 

2. Modbus協議源代碼簡介

 

2.1 關於modbus中的常見兩種寄存器區別

        保持寄存器:指可以通過通信命令讀或者寫的寄存器;通常是一些功能控制寄存器或者輸出寄存器等。不同的設計中,有些保持寄存器是掉電保持;有些則不然。

        輸入寄存器:指只能讀不能寫的寄存器,通常是狀態寄存器或者是輸入結果寄存器等。

        線圈寄存器,可以類比為開關量,每一個bit都對應一個信號的開關狀態。所以一個byte就可以同時控制8路的信號。

        離散輸入寄存器:相當於線圈寄存器的只讀模式,每個bit表示一個開關量,而他的開關量只能讀取輸入的開關信號,無法寫入。

2.2  Modbus開源庫常用配置接口

1)modbus_t* modbus_new_rtu(const char *device,

                         int baud, char parity, int data_bit,

                         int stop_bit)

modbus_new_rtu函數用於生成Modbus的句柄,在本函數中可以設置通

信協議中的波特率、校驗位、數據長度以及停止位,其返回值為通過設置后生成的句柄,用於在讀寫數據時使用,每個句柄可以執行一個modbus指令。如果這些配置參數有誤,就會返回一個空指針。

2)static int _modbus_rtu_connect(modbus_t *ctx)

       本函數主要功能是將通信串口設置為rtu模式。

3)int modbus_set_slave(modbus_t *ctx, int slave)

        本函數設置本句柄的從機號。

 

2.3 Modbus主機通信常用接口

1)int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)

        本函數為將數組中的數據寫入到遠端設備(從機)的寄存器中,寫入的地址位addr,長度為nb個寄存器。

2)int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)

        本函數將遠端設備(從機)保持寄存器中的數據復制到數組dest中。

3)int modbus_read_input_registers(modbus_t *ctx, int addr, int nb,

                                uint16_t *dest)

         本函數讀取遠端設備(從機)地址為addr輸入寄存器中的數據,數據長度為nb。

 

2.4 Modbus從機通信主要接口

1)int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)

        本函數可以用於處理來自主機的請求,返回接受到的字符的數量,如果成功,則返回uint8_t數組中的消息(即主機發送的命令),否則返回-1。

 

2)int modbus_reply(modbus_t *ctx, const uint8_t *req,

                 int req_length, modbus_mapping_t *mb_mapping)

       本函數負責在接受到請求后,分析請求並生成響應消息,並且發送到主機。如果請求屬性為廣播,那么不發送響應消息。

三、 調試問題分享

  在調試中,從機的Server進程會經常出現崩潰,最后發現在Server經常每次處理配置變更時,都會重新new出新的modbus句柄,但卻不釋放原有句柄,這種處理會導致多次修改Modbus通信配置時,從機Server進程崩潰。

         解決方案:在程序中判斷,當modbus句柄已經存在時,此時更新配置后,不再new出新的句柄,而是調用接口 modbus_close(), modbus_free()釋放句柄中的配置,然后用更新后的配置重新設置句柄參數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM