網絡編程--串口通訊--ModbusTCP


簡介

Modbus由MODICON公司於1979年開發,是一種工業現場總線協議標准。1996年施耐德公司推出基於以太網TCP/IP的Modbus協議:ModbusTCP。

Modbus協議是一項應用層報文傳輸協議,包括ASCII、RTU、TCP三種報文類型。

標准的Modbus協議物理層接口有RS232、RS422、RS485和以太網接口,采用master/slave方式通信。

ModbusTCP數據幀

ModbusTCP的數據幀可分為兩部分:MBAP+PDU

報文頭MBAP

MBAP為報文頭,長度為7字節,組成如下:

事務處理標識 協議標識 長度 單元標識符
2字節 2字節 2字節 1字節

 

內容 解釋
事務處理標識 可以理解為報文的序列號,一般每次通信之后就要加1以區別不同的通信數據報文。
協議標識符 00 00表示ModbusTCP協議。
長度 表示接下來的數據長度,單位為字節。
單元標識符 可以理解為設備地址。

幀結構PDU

PDU由功能碼+數據組成。功能碼為1字節,數據長度不定,由具體功能決定。

功能碼

Modbus的操作對象有四種:線圈、離散輸入、輸入寄存器、保持寄存器。

對象 含義
線圈 PLC的輸出位,開關量,在Modbus中可讀可寫
離散量 PLC的輸入位,開關量,在Modbus中只讀
輸入寄存器 PLC中只能從模擬量輸入端改變的寄存器,在Modbus中只讀
保持寄存器 PLC中用於輸出模擬量信號的寄存器,在Modbus中可讀可寫

根據對象的不同,Modbus的功能碼有:

功能碼 含義
0x01 讀線圈
0x02 讀離散量輸入
0x03 讀保持寄存器
0x04 讀輸入寄存器
0x05 寫單個線圈
0x06 寫單個保持寄存器
0x10 寫多個保持寄存器
0x0F 寫多個線圈

PDU詳細結構

0x01:讀線圈

在從站中讀1~2000個連續線圈狀態,ON=1,OFF=0

  • 請求:MBAP 功能碼 起始地址H 起始地址L 數量H 數量L(共12字節)
  • 響應:MBAP 功能碼 數據長度 數據(一個地址的數據為1位)
  • 如:在從站0x01中,讀取開始地址為0x0002的線圈數據,讀0x0008位
    00 01 00 00 00 06 01 01 00 02 00 08
  • 回:數據長度為0x01個字節,數據為0x01,第一個線圈為ON,其余為OFF
    00 01 00 00 00 04 01 01 01 01

0x05:寫單個線圈
將從站中的一個輸出寫成ON或OFF,0xFF00請求輸出為ON,0x000請求輸出為OFF

  • 請求:MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節)
  • 響應:MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節)
  • 如:將地址為0x0003的線圈設為ON
    00 01 00 00 00 06 01 05 00 03 FF 00
  • 回:寫入成功
    00 01 00 00 00 06 01 05 00 03 FF 00

0x0F:寫多個線圈
將一個從站中的一個線圈序列的每個線圈都強制為ON或OFF,數據域中置1的位請求相應輸出位ON,置0的位請求響應輸出為OFF

  • 請求:MBAP 功能碼 起始地址H 起始地址L 輸出數量H 輸出數量L 字節長度 輸出值H 輸出值L
  • 響應:MBAP 功能碼 起始地址H 起始地址L 輸出數量H 輸出數量L

0x02:讀離散量輸入
從一個從站中讀1~2000個連續的離散量輸入狀態

  • 請求:MBAP 功能碼 起始地址H 起始地址L 數量H 數量L(共12字節)
  • 響應:MBAP 功能碼 數據長度 數據(長度:9+ceil(數量/8))
  • 如:從地址0x0000開始讀0x0012個離散量輸入
    00 01 00 00 00 06 01 02 00 00 00 12
  • 回:數據長度為0x03個字節,數據為0x01 04 00,表示第一個離散量輸入和第11個離散量輸入為ON,其余為OFF
    00 01 00 00 00 06 01 02 03 01 04 00

0x04:讀輸入寄存器
從一個遠程設備中讀1~2000個連續輸入寄存器

  • 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
  • 響應:MBAP 功能碼 數據長度 寄存器數據(長度:9+寄存器數量×2)
  • 如:讀起始地址為0x0002,數量為0x0005的寄存器數據
    00 01 00 00 00 06 01 04 00 02 00 05
  • 回:數據長度為0x0A,第一個寄存器的數據為0x0c,其余為0x00
    00 01 00 00 00 0D 01 04 0A 00 0C 00 00 00 00 00 00 00 00

0x03:讀保持寄存器
從遠程設備中讀保持寄存器連續塊的內容

  • 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
  • 響應:MBAP 功能碼 數據長度 寄存器數據(長度:9+寄存器數量×2)
  • 如:起始地址是0x0000,寄存器數量是 0x0003
    00 01 00 00 00 06 01 03 00 00 00 03
  • 回:數據長度為0x06,第一個寄存器的數據為0x21,其余為0x00
    00 01 00 00 00 09 01 03 06 00 21 00 00 00 00

0x06:寫單個保持寄存器
在一個遠程設備中寫一個保持寄存器

  • 請求:MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節)
  • 響應:MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節)
  • 如:向地址是0x0000的寄存器寫入數據0x000A
    00 01 00 00 00 06 01 06 00 00 00 0A
  • 回:寫入成功
    00 01 00 00 00 06 01 06 00 00 00 0A

0x10:寫多個保持寄存器
在一個遠程設備中寫連續寄存器塊(1~123個寄存器)

  • 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L 字節長度 寄存器值(13+寄存器數量×2)
  • 響應:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
  • 如:向起始地址為0x0000,數量為0x0001的寄存器寫入數據,數據長度為0x02,數據為0x000F
    00 01 00 00 00 09 01 10 00 00 00 01 02 00 0F
  • 回:寫入成功
    00 01 00 00 00 06 01 10 00 00 00 01

Modbus TCP 示例報文

原文鏈接:https://blog.csdn.net/mikasoi/article/details/81782159

ModBusTcp與串行鏈路Modbus的數據域是一致的,具體數據域可以參考串行Modbus。這里給出幾個ModbusTcp的鏈路解析說明,輔助新人分析報文。

ModbusTCP通信

通信方式

Modbus設備可分為主站(poll)和從站(slave)。主站只有一個,從站有多個,主站向各從站發送請求幀,從站給予響應。在使用TCP通信時,主站為client端,主動建立連接;從站為server端,等待連接。

  • 主站請求:功能碼+數據
  • 從站正常響應:請求功能碼+響應數據
  • 從站異常響應:異常功能碼+異常碼,其中異常功能碼即將請求功能碼的最高有效位置1,異常碼指示差錯類型
  • 注意:需要超時管理機制,避免無期限的等待可能不出現的應答

IANA(Internet Assigned Numbers Authority,互聯網編號分配管理機構)給Modbus協議賦予TCP端口號為502,這是目前在儀表與自動化行業中唯一分配到的端口號。

通信過程

  1. connect 建立TCP連接
  2. 准備Modbus報文
  3. 使用send命令發送報文
  4. 在同一連接下等待應答
  5. 使用recv命令讀取報文,完成一次數據交換
  6. 通信任務結束時,關閉TCP連接

4 仿真軟件

  • Modbus poll 和Modbus slave是一組Modbus仿真軟件,可以實現Modbus RTU、TCP、串口仿真等。
  • 在ModbusTCP中,Modbus poll 作為客戶端請求數據,Modbus slave 作為服務器端處理請求。
  • 使用c語言編寫客戶端連接Modbus slave時,注意數據格式,一條指令一次性發出,否則連接會出錯。
  • 使用軟件時,需要指定功能碼,在setup->slave definition或者poll definition中進行設置。
    – slave ID:從站編號(事務標識符)
    – function:功能碼,0x01對應線圈操作,0x02對應離散量操作,0x03對應保持寄存器操作,0x04對應輸入寄存器操作
    – address:開始地址
    – quantity:寄存器/線圈/離散量 的數量

參考:
https://wenku.baidu.com/view/c2a9e1cc376baf1ffd4fad5c.html
https://blog.csdn.net/zwxue251/article/details/24154951
https://blog.csdn.net/lakerszhy/article/details/68927178?locationNum=4&fps=1

一些概念

原文鏈接:https://wenku.baidu.com/view/55595d0690c69ec3d5bb75ed.html

在工業自動化控制中,經常會遇到開關量,數字量,模擬量,離散量,脈沖量等各種概念,而人們在實際應用中,對於這些概念又很容易混淆。現將各種概念羅列如下:
    

1.開關量:

一般指的是觸點的“開”與“關”的狀態,一般在計算機設備中也會用“0”或“1”來表示開關量的狀態。開關量分為有源開關量信號和無源開關量信號,有源開關量信號指的是“開”與“關”的狀態是帶電源的信號,專業叫法為躍階信號,可以理解為脈沖量,一般的都有220VAC, 110VAC,24VDC,12VDC等信號,無源開關量信號指的是“開”和“關”的狀態時不帶電源的信號,一般又稱之為干接點。電阻測試法為電阻0或無窮大。    

2.數字量:

很多人會將數字量與開關量混淆,也將其與模擬量混淆。數字量在時間和數量上都是離散的物理量,其表示的信號則為數字信號。數字量是由0和1組成的信號,經過編碼形成有規律的信號,量化后的模擬量就是數字量。    

3.模擬量:

模擬量的概念與數字量相對應,但是經過量化之后又可以轉化為數字量。模擬量是在時間和數量上都是連續的物理量,其表示的信號則為模擬信號。模擬量在連續的變化過程中任何一個取值都是一個具體有意義的物理量,如溫度,電壓,電流等。    

4.離散量:

離散量是將模擬量離散化之后得到的物理量。即任何儀器設備對於模擬量都不可能有個完全精確的表示,因為他們都有一個采樣周期,在該采樣周期內,其物理量的數值都是不變的,而實際上的模擬量則是變化的。這樣就將模擬量離散化,成為了離散量。   

5.脈沖量:

脈沖量就是瞬間電壓或電流由某一值躍變到另一值的信號量。在量化后,其變化持續有規律就是數字量,如果其由0變成某一固定值並保持不變,其就是開關量。   

綜上所述,模擬量就是在某個過程中時間和數量連續變化的物理量,由於在實際的應用中,所有的儀器設備對於外界數據的采集都有一個采樣周期,其采集的數據只有在下一個采樣周期開始時才有變動,采樣周期內其數值並不隨模擬量的變化而變動。
這樣就將模擬量離散化了,例如:某設備的采樣周期為1秒,其在第五秒的時間采集的溫度為35度,而第六秒的溫度為36度,該設備就只能標稱第五秒時間溫度35度,第六秒時間溫度36度,而第五點五秒的時間其標稱也只是35度,但是其實際的模擬量是35.5度。這樣就將模擬信號離散化。其采集的數據就是離散化了,不再是連續的模擬量信號。
由於計算機只識別0和1兩個信號,即開關量信號,用其來表示數值都是使用數字串來表示,由於計算能力的問題,其數字串不能無限長,即其表達的精度也是有限的,同樣的以溫度為例,由於數字串限制,其表達溫度的精度只能達到0.1度,小於該單位的數值則不能被標稱,這樣就必須將離散量進行量化,將其變為數字量。即35.68度的溫度則表示為35.6度。


ModbusTcp協議客戶端實現:

 

以下程序是我用NModbus4框架實現,該框架還支持RTU、Ascii格式,但現在TCP是發展趨勢,項目中有用到,固使用tcp格式做了個Demo。

NModbus4框架源碼地址: https://github.com/NModbus4/NModbus4

 

界面如下:

程序下載

 


免責聲明!

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



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