Qt编写Modbus从机程序
上一個網(wǎng)文我們使用MODSCAN32軟件和串口助手調(diào)試了Modbus協(xié)議,我們之前還分享過使用Qt編寫自己的串口助手,今天我們在上次分享的串口助手的源碼基礎上,使用Qt編寫一個Modbus從機程序,讓其與MODSCAN32軟件實現(xiàn)數(shù)據(jù)交互。
實現(xiàn)目標
-
熟悉Modbus協(xié)議0x03和0x06功能碼
-
熟悉QTableView控件的使用
-
Qt編寫的Modbus從設備與ModScan32軟件進行數(shù)據(jù)交互
結(jié)果展示
-
改變QTableView控件中某一個單元格的值
-
MODSCAN32軟件實時獲得QTableView控件中的值
-
MODSCAN32軟件中修改某一個寄存器的值,QTableView控件隨之改變
素材獲取
上面視頻中獲取源碼的獲取方式,歡迎關(guān)注小哈哥的視頻號,更多精彩敬請期待。
讀保持寄存器功能碼0x03
當主機發(fā)送0x03功能碼時,表明主機想要獲取從機某些寄存器里的內(nèi)容。
舉例: 請求讀寄存器108~110:
由上圖我們可知,寄存器108的內(nèi)容為02 2B,即十進制的555,寄存器109~110的內(nèi)容分別為十六進制的00 00 和 00 64,或十進制的0和100。
寫單個寄存器功能碼0x06
0x06功能碼是主機用來向從機的某個寄存器寫數(shù)據(jù),一次只能操作一個寄存器。
使用功能碼0x06寫單個保持寄存器。
舉例: 請求將十六進制00 03寫入寄存器2。
寫多個保持寄存器功能碼0x10
將十六進制 00 0A 和 01 02 寫入從寄存器 2 開始的兩個寄存器的實例:
注意:上面截圖的實例中,未包含地址位和校驗碼。
0x03和0x06功能碼調(diào)試
主從機寄存器地址設置不一致
上面主從機地址設置不一致的返回:
MODSIM32收到的數(shù)據(jù)包:01 03 00 00 00 06 C5 C8
MODSIM32返回的數(shù)據(jù)包:01 83 02 C0 F1
主從機寄存器地址一致
MODSIM32收到的數(shù)據(jù)包:01 03 00 00 00 06 C5 C8
MODSIM32返回的數(shù)據(jù)包:01 03 0C 01 00 00 00 00 00 00 00 00 00 00 00 6E B3
主機修改值
使用Modbus功能碼0x06:寫單路寄存器,實現(xiàn)對從機單個寄存器值的修改。
修改地址2的寄存器值為0x00FF
MODSCAN32發(fā)送的數(shù)據(jù)包:01 06 00 01 00 FF 98 4A
MODSIM32返回的應答包:01 06 00 01 00 FF 98 4A
主機發(fā)送的報文格式:
| 從機地址 | 1 | 01 |
| 功能碼 | 1 | 06 |
| 起始地址 | 2 | 0x0001 |
| 寫入數(shù)據(jù) | 2 | 0x00FF |
| CRC碼 | 2 | 0x984A |
從機響應返回的報文格式,與主機發(fā)送的報文格式及數(shù)據(jù)內(nèi)容完全相同。
修改地址6的寄存器值為0xFF00
從機修改值
修改地址4的寄存器值為0x0008
由上我們可以看出來,從機修改完值無需上傳數(shù)據(jù)包(因為Modbus是主從模式,從機不能主動上傳數(shù)據(jù)),等待下次主機查詢寄存器狀態(tài)的時候,上報即可。
注意:上面演示使用的ModSim32軟件作為從機,MODSCAN32軟件作為主機。
基于Qt的Modbus從機程序
有了上面的演示,我們知道了主機發(fā)送不同功能碼的時候,我們應該返回給主機什么樣的數(shù)據(jù)內(nèi)容,下面我們在之前我們分享的《 使用Qt打造屬于自己的串口調(diào)試助手 》的基礎上,完成0x03和0x06功能碼的應答,最終程序的界面顯示如下。
因為Modbus協(xié)議是主從模式,從機不會主動發(fā)數(shù)據(jù)包至主機,從機只要解析接收到的數(shù)據(jù)包,然后根據(jù)協(xié)議規(guī)定返回對應的內(nèi)容即可。
所以我們的Qt程序,主要工作就是解析收到的串口數(shù)據(jù),因此,在串口接收函數(shù)中,解析收到的數(shù)據(jù)包具體需要做如下工作:
-
將接收到的前6個字節(jié)數(shù)據(jù)進行CRC計算;
-
CRC計算的結(jié)果跟接收到的第7、第8字節(jié)比較,如果一致,證明數(shù)據(jù)包沒有問題;
-
如果CRC正確,那么根據(jù)接收到的第2字節(jié)進行判斷,當?shù)?字節(jié)為0x03時,為Modbus讀寄存器的操作;當?shù)?字節(jié)為0x06時,為Modbus寫單寄存器的操作;
-
如果功能碼為0x03,則獲取TableView第2列內(nèi)的所有數(shù)據(jù),作為返回數(shù)據(jù)包的寄存器值,然后將地址位、功能碼、數(shù)據(jù)長度、寄存器值這些進行CRC校驗,然后組成一個數(shù)據(jù)包發(fā)送至主機;
-
如果功能碼為0x06,則將收到數(shù)據(jù)包的數(shù)據(jù)位組成一個WORD類型的整形數(shù),根據(jù)寄存器地址,將其賦值到TableView中對應的單元格中。
Qt實現(xiàn)的Modbus從機程序大家可以參考本文提供的源碼。
總結(jié)
經(jīng)過我們這兩次modbus協(xié)議的分享,大家可以試試其他功能碼的發(fā)送與應答,自己隨意玩起吧。
參考閱讀
干貨 | Modbus協(xié)議調(diào)試分享
485型風速和風向變送器數(shù)據(jù)包解析
CRC校驗碼簡介及CRC16的計算方法
使用Qt打造屬于自己的串口調(diào)試助手
歡迎關(guān)注
小伙伴們可加微信[chengxuyuanxiaoha]進技術(shù)交流群,與更多同道中人一起成長。
聲明:文中軟件僅供學習使用,請支持正版。
總結(jié)
以上是生活随笔為你收集整理的Qt编写Modbus从机程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TCP三次握手(待细研究)
- 下一篇: 【图像处理】——鼠标点击图像的一处,获得