自我們開源了我們的Modbus協議棧之后,就一直有朋友來信說希望提供示例。這次我們整理了幾個例子以供參考。
1、應用實例規划
在這次的實例中,我們使用的目標板擁有一個以太網接口、一個RS232串行接口和一個RS485串行接口,所以我們規划實現:
-
一個Modbus TCP Server實例
-
一個Modbus RTU Slave實例
-
一個Modbus RTU Master實例
這三個實例並不是獨立的,Modbus TCP Server和Modbus RTU Slave它們實現的實際上是同一站點,就是本地從站,擁有共同的數據處理回調函數,所不同的只是它們的* 協議解析及報文生成的方式是不同的。Modbus RTU Master原則上來說與本地從站是沒有關系的,但為了便於查看數據,我們將它從遠程從站獲取的的數據存放到本地從站的數據表,這樣我們就可以從上位機上看到遠程從站的數據。據此我們設計軟件訪問的結構圖如下:
在這個例子中,我們在STM32F407平台上采用同一協議棧實現基於以太網口的Modbus TCP Server;基於RS232串口的Modbus RTU Slave以及基於RS485串口的Modbus RTU Master。就是說我們在同一個項目中,同時實現了這三個實例以說明協議棧的使用方法。
2、Modbus TCP Server實例
在我們的目標平台上有一個以太網口,我們將其設計為Modbus TCP Server的接口。我們設計一下Modbus TCP Server的數據表,首先是本地數據,我們設計使用8個保持寄存器和8個線圈量。這些量中,我們特意設計其屬性既有只讀的數據,又有可讀可寫的數據。同時將其數據類型設定有單精度浮點數、32位無符號整數、16位無符號整數以及布爾量。這樣我們就可以展示協議在不同數據模式及屬性上的操作。
1 | uint32_t | beatTime | 心跳檢測 | 40001 | 只讀 |
---|---|---|---|---|---|
2 | float | mbAI1 | 模擬量測試 | 40003 | 只讀 |
3 | float | mbAO1 | 模擬量測試 | 40005 | 讀寫 |
4 | uint16_t | mbAI2 | 模擬量測試 | 40007 | 只讀 |
5 | uint16_t | mbAO2 | 模擬量測試 | 40008 | 讀寫 |
1 | bool | mbDI1 | 數字量輸入參數1 | 1 | 只讀 |
---|---|---|---|---|---|
2 | bool | mbDI2 | 數字量輸入參數2 | 2 | 只讀 |
3 | bool | mbDI3 | 數字量輸入參數3 | 3 | 只讀 |
4 | bool | mbDI4 | 數字量輸入參數4 | 4 | 只讀 |
5 | bool | mbDO1 | 數字量輸出參數1 | 5 | 讀寫 |
6 | bool | mbDO2 | 數字量輸出參數2 | 6 | 讀寫 |
7 | bool | mbDO3 | 數字量輸出參數3 | 7 | 讀寫 |
8 | bool | mbDO4 | 數字量輸出參數4 | 8 | 讀寫 |
除了上述這些參數外,我們處於操作方便及便於監控的考慮將從下位讀出來的數據與設計到統一的數據表中。就跟在個數據類型的后面,每個從站8個個保持寄存器和8個線圈量。數據屬性同樣有只讀和讀寫、數據類型也同樣有浮點數、整數及布爾量。關於從站的數據將在后面詳細表述。
3、Modbus RTU Slave實例
在我們的目標平台上USART1為RS232模式,我們將其設計為Modbus RTU Slave的接口,同樣的,我們設計一下Modbus TCP Server的數據表,首先是本地數據,我們設計使用8個保持寄存器和8個線圈量。這些量中,我們特意設計其屬性既有只讀的數據,又有可讀可寫的數據。同時將其數據類型設定有單精度浮點數、32位無符號整數、16位無符號整數以及布爾量。這樣我們就可以展示協議在不同數據模式及屬性上的操作。
1 | uint32_t | beatTime | 心跳檢測 | 40001 | 只讀 |
---|---|---|---|---|---|
2 | float | mbAI1 | 模擬量測試 | 40003 | 只讀 |
3 | float | mbAO1 | 模擬量測試 | 40005 | 讀寫 |
4 | uint16_t | mbAI2 | 模擬量測試 | 40007 | 只讀 |
5 | uint16_t | mbAO2 | 模擬量測試 | 40008 | 讀寫 |
1 | bool | mbDI1 | 數字量輸入參數1 | 1 | 只讀 |
---|---|---|---|---|---|
2 | bool | mbDI2 | 數字量輸入參數2 | 2 | 只讀 |
3 | bool | mbDI3 | 數字量輸入參數3 | 3 | 只讀 |
4 | bool | mbDI4 | 數字量輸入參數4 | 4 | 只讀 |
5 | bool | mbDO1 | 數字量輸出參數1 | 5 | 讀寫 |
6 | bool | mbDO2 | 數字量輸出參數2 | 6 | 讀寫 |
7 | bool | mbDO3 | 數字量輸出參數3 | 7 | 讀寫 |
8 | bool | mbDO4 | 數字量輸出參數4 | 8 | 讀寫 |
除了上述這些參數外,我們處於操作方便及便於監控的考慮將從下位讀出來的數據與設計到統一的數據表中。就跟在個數據類型的后面,每個從站8個個保持寄存器和8個線圈量。數據屬性同樣有只讀和讀寫、數據類型也同樣有浮點數、整數及布爾量。關於從站的數據將在后面詳細表述。
關於Modbus RTU Slave我們將其本地站地址設定為1,波特率115200,8位數據位,1位停止位,無校驗。
4、Modbus RTU Master實例
在我們的目標平台上USART3為RS485模式,我們將其設計為Modbus RTU Master,其訪問的目標從站數量為4個,站地址分別為:1、2、3、4,包括線圈量8個,和保持寄存器量8個。數據類型設定有單精度浮點數、32位無符號整數、16位無符號整數以及布爾量。數據屬性設置有只讀數據和可讀寫數據。
*序號* | *數據類型* | *變量名稱* | *參數名稱* | *地址* | *讀寫屬性* |
---|---|---|---|---|---|
1 | float | mbSalve1AI1 | 目標從站1的模擬量輸入參數1 | 40001 | 只讀 |
2 | uint32_t | mbSalve1AI2 | 目標從站1的模擬量輸入參數2 | 40003 | 只讀 |
5 | uint16_t | mbSalve1AI3 | 目標從站1的模擬量輸入參數3 | 40005 | 只讀 |
6 | uint16_t | mbSalve1AO1 | 目標從站1的模擬量輸出參數1 | 40006 | 讀寫 |
7 | uint16_t | mbSalve1AO2 | 目標從站1的模擬量輸出參數2 | 40007 | 讀寫 |
8 | uint16_t | mbSalve1AO3 | 目標從站1的模擬量輸出參數3 | 40008 | 讀寫 |
1 | bool | mbSalve1DI1 | 目標從站1的數字量輸入參數1 | 1 | 只讀 |
2 | bool | mbSalve1DI2 | 目標從站1的數字量輸入參數2 | 2 | 只讀 |
3 | bool | mbSalve1DI3 | 目標從站1的數字量輸入參數3 | 3 | 只讀 |
4 | bool | mbSalve1DI4 | 目標從站1的數字量輸入參數4 | 4 | 只讀 |
5 | bool | mbSalve1DO1 | 目標從站1的數字量輸出參數1 | 5 | 讀寫 |
6 | bool | mbSalve1DO2 | 目標從站1的數字量輸出參數2 | 6 | 讀寫 |
7 | bool | mbSalve1DO3 | 目標從站1的數字量輸出參數3 | 7 | 讀寫 |
8 | bool | mbSalve1DO4 | 目標從站1的數字量輸出參數4 | 8 | 讀寫 |
其它3個從站的數據設計與此站相同。關於Modbus RTU Master我們將其波特率115200,8位數據位,1位停止位,無校驗。其訪問的4台從站也照此設置。
5、幾點說明
首先聲明這些實例都是基於我們開源的Modbus協議棧的,而此協議棧已經發布到Github,其地址為:https://github.com/foxclever/Modbus。
同時也發布到碼雲,其地址為:https://gitee.com/ErichMoonan/Modbus。
在開源的協議棧中example文件夾下即是本次發布的例子。
將四台從站讀取回來的數據添加到本站數據表中后,每台從站都是線圈量8個,和保持寄存器量8個。本站數據也是線圈量8個,和保持寄存器量8個。所以上位機能監控到的數據范圍是線圈量40個,和保持寄存器量40個。地址都是從0開始。