ModbusTCP協議簡介與程式設計流程圖

一杯清酒邀明月發表於2024-03-09

  本文主要目的是為了寫一個簡單的ModbusTCP伺服器-客戶端程式而記錄的知識點,裡面包含了程式設計所需要的必要背景知識和協議解析流程圖。

Modbus基本資料型別
  Modbus有四種基本資料型別:

  • 離散量輸入:客戶端只能讀取它,由伺服器提供,佔1個位元位,可以傳輸現實中的開關量輸入,比如接近開關的通斷資訊等。
  • 線圈:客戶端可以可寫入和讀取,伺服器根據客戶端的設定改變其值,佔1個位元位,可以控制現實中的繼電器的吸合與斷開。
  • 輸入暫存器:客戶端只能讀取它,最小單位是16位元字,它也可以傳輸8位資料。傳輸超過16位元資料的時候需要多個輸入暫存器,現實中的溫度,電壓等資料可透過輸入暫存器來傳輸。
  • 保持暫存器:客戶端可以寫入或者讀取,最小單位是16位元字,可以設定一些引數,以及現實中的電壓等物理量。

ModbusTCP資料格式
  一個正常的ModbusTCP資料幀包括以下三部分:

  這三部分合稱為ADU,也就是應用資料單元,其中功能碼和資料合稱為PDU,也就是協議資料單元。ADU中的MBAP(MODBUS Application Protocol)是ModbusTCP特有的內容。PDU在所有Modbus中格式完全相同。
  ModbusTCP資料幀使用埠502傳送,埠502是網際網路組織專門為MODBUS-TCP協議保留的埠號。

MBAP報文頭格式:
  MBAP報文頭(MODBUS協議報文頭)共7個位元組,其含義如下:

  •   事務元識別符號:2位元組,由於客戶端可以同時傳送多條請求,為了區分伺服器響應的是哪條請求,客戶端在請求幀中使用計數器值填充此區域,伺服器可以在響應幀中返回相同的計數值供客戶端來區分請求。
  •   協議識別符號:2位元組,保持為0,表示是MODBUS協議
  • 長度:2位元組,後續位元組數
  •   單元識別符號:1位元組,對於需要轉發給序列鏈路的MODBUS裝置才有意義,一般無需考慮,寫0即可。

PDU格式
  由於不同功能碼對應著不同的資料格式,因此需要將功能碼和資料部分一起闡釋,我這裡只介紹我的程式將要涉及到的功能碼3和16。之所以只選擇了這兩個功能碼,是由於這兩個功能碼基本上就可以涵蓋資料採集相關的所有功能,寫多個暫存器可以設定採集引數、DA輸出、設定開關量輸出……讀多個暫存器可以讀取各種採集結果。

03 (0x03)讀保持暫存器

  每個暫存器的寬度是16位,2個位元組,由於是大端模式(Big-endian),因此高位元組在前,低位元組在後,其具體資料格式如下:
請求:

功能碼1個位元組3(0x03)
起始地址 2個位元組 0~65535(0xFFFFF)
暫存器數量 2個位元組 N=1~125(0x7D)
響應:
功能碼1個位元組3(0x03)
位元組數 1個位元組 N*2
暫存器值 N*2個位元組

舉例:
下列是請求讀地址偏移0一個暫存器的值,暫存器值是0
位元組序號(10進位制):00 01 02 03 04 05 06 07 08 09 10 11
傳送字元(16進位制):00 00 00 00 00 06 00 03 00 00 00 01
接受字元(16進位制):00 00 00 00 00 05 00 03 02 00 00

暫存器數量是受限於MODBUS-RTU的協議資料幀(PDU)長度不能超過252,PDU中的功能碼和位元組數佔用兩個位元組,因此(252-2)/2=125

讀保持暫存器流程圖

16 (0x10)寫保持暫存器
  寫保持暫存器是讀多個暫存器的反向操作,它可以與讀多個暫存器是同一個功能項的讀寫操作,也可以是不同功能項的單獨操作。例如在DA(數模轉換)中,使用寫多個暫存器設定DA輸出值,然後可以用讀多個暫存器返回之前設定的值。也可以相同的地址,返回AD(模數轉換)的採集值,這取決於實際應用。其具體格式如下:
請求:

功能碼1個位元組16(0x10)
起始地址 2個位元組 0~65535(0xFFFFF)
暫存器數量 2個位元組 N=1~123(0x7B)
位元組數 1個位元組 2*N
暫存器值 N*2個位元組 大端排列的值

PDU最大位元組數為252,減去功能碼,起始地址,暫存器數量,位元組數所佔用的6個位元組為246,因此暫存器數量最大為123。

響應:

功能碼1個位元組16(0x10)
起始地址 2個位元組 與請求起始地址相同
暫存器數量 2個位元組 N

舉例:
下列是請求寫地址偏移0一個暫存器的值,暫存器值是0
位元組序號(10進位制):00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
傳送字元(16進位制):00 00 00 00 00 09 00 10 00 00 00 01 02 00 00
接受字元(16進位制):00 00 00 00 00 06 00 10 00 00 00 01

寫多個暫存器流程圖:

異常響應

  當請求失敗的時候,伺服器將會返回異常響應,異常響應幀會在功能碼的位置將原有功能碼+0x80,後面的資料是異常碼,其具體格式如下:
異常響應:

功能碼1個位元組0x80+請求功能碼
異常碼    1個位元組   常用異常碼:
01:不支援的功能碼
02:地址錯誤,起始地址+暫存器數量如果超範圍,也屬於地址錯誤
03:資料錯誤,這裡的資料還包括了PDU資料本身,比如請求的暫存器數量超過了PDU所允許的最大長度。
04:從站故障,在伺服器處理請求過程中遇到了錯誤。

MODBUS-TCP請求響應流程
  伺服器在接收到客戶端請求後,首先判斷協議識別符號,如果是MODBUS協議,才能繼續處理,然後根據MBAP報文頭中的後續位元組數來拆出一個完整的資料幀。如果客戶端是使用請求-響應方式來傳送請求,則伺服器接收到的每包資料都應該是且只有一個完整的資料包。最後根據功能碼來將請求交給各個功能碼子程式來處理。流程圖如下:

相關文章