加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 實(shí)現(xiàn)目標(biāo)
    • 結(jié)果展示
    • 素材獲取
    • 讀保持寄存器功能碼0x03
    • 寫(xiě)單個(gè)寄存器功能碼0x06
    •  
    • 寫(xiě)多個(gè)保持寄存器功能碼0x10
    • 0x03和0x06功能碼調(diào)試
    • 基于Qt的Modbus從機(jī)程序
    • 總結(jié)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Qt編寫(xiě)Modbus從機(jī)程序

2021/03/22
404
閱讀需 6 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

上一個(gè)網(wǎng)文我們使用MODSCAN32軟件和串口助手調(diào)試了Modbus協(xié)議,我們之前還分享過(guò)使用Qt編寫(xiě)自己的串口助手,今天我們?cè)谏洗畏窒淼拇谥值脑创a基礎(chǔ)上,使用Qt編寫(xiě)一個(gè)Modbus從機(jī)程序,讓其與MODSCAN32軟件實(shí)現(xiàn)數(shù)據(jù)交互。

實(shí)現(xiàn)目標(biāo)

熟悉Modbus協(xié)議0x03和0x06功能碼

熟悉QTableView控件的使用

Qt編寫(xiě)的Modbus從設(shè)備與ModScan32軟件進(jìn)行數(shù)據(jù)交互

結(jié)果展示

素材獲取

在上面視頻中有源碼的獲取方式,歡迎關(guān)注小哈哥的視頻號(hào),更多精彩敬請(qǐng)期待。

讀保持寄存器功能碼0x03

當(dāng)主機(jī)發(fā)送0x03功能碼時(shí),表明主機(jī)想要獲取從機(jī)某些寄存器里的內(nèi)容。

舉例: 請(qǐng)求讀寄存器108~110:

由上圖我們可知,寄存器108的內(nèi)容為02 2B,即十進(jìn)制的555,寄存器109~110的內(nèi)容分別為十六進(jìn)制的00 00 和 00 64,或十進(jìn)制的0和100。

寫(xiě)單個(gè)寄存器功能碼0x06

0x06功能碼是主機(jī)用來(lái)向從機(jī)的某個(gè)寄存器寫(xiě)數(shù)據(jù),一次只能操作一個(gè)寄存器。

使用功能碼0x06寫(xiě)單個(gè)保持寄存器。

舉例: 請(qǐng)求將十六進(jìn)制00 03寫(xiě)入寄存器2。

 

寫(xiě)多個(gè)保持寄存器功能碼0x10

將十六進(jìn)制 00 0A 和 01 02 寫(xiě)入從寄存器 2 開(kāi)始的兩個(gè)寄存器的實(shí)例:

注意:上面截圖的實(shí)例中,未包含地址位和校驗(yàn)碼。

0x03和0x06功能碼調(diào)試

主從機(jī)寄存器地址設(shè)置不一致

上面主從機(jī)寄存器地址設(shè)置不一致的返回:MODSIM32收到的數(shù)據(jù)包:01 03 00 00 00 06 C5 C8

MODSIM32返回的數(shù)據(jù)包:01 83 02 C0 F1

 

主從機(jī)寄存器地址一致

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

 

主機(jī)修改值

使用Modbus功能碼0x06:寫(xiě)單路寄存器,實(shí)現(xiàn)對(duì)從機(jī)單個(gè)寄存器值的修改。

修改地址2的寄存器值為0x00FF

MODSCAN32發(fā)送的數(shù)據(jù)包:01 06 00 01 00 FF 98 4A

MODSIM32返回的應(yīng)答包:01 06 00 01 00 FF 98 4A

主機(jī)發(fā)送的報(bào)文格式:

主機(jī)發(fā)送 字節(jié)數(shù) 發(fā)送的信息
從機(jī)地址 1 01
功能碼 1 06
起始地址 2 0x0001
寫(xiě)入數(shù)據(jù) 2 0x00FF
CRC碼 2 0x984A

從機(jī)響應(yīng)返回的報(bào)文格式,與主機(jī)發(fā)送的報(bào)文格式及數(shù)據(jù)內(nèi)容完全相同。

 

修改地址6的寄存器值為0xFF00

 

從機(jī)修改值

修改地址4的寄存器值為0x0008

由上我們可以看出來(lái),從機(jī)修改完值無(wú)需上傳數(shù)據(jù)包(因?yàn)镸odbus是主從模式,從機(jī)不能主動(dòng)上傳數(shù)據(jù)),等待下次主機(jī)查詢(xún)寄存器狀態(tài)的時(shí)候,上報(bào)即可。

注意:上面演示使用的ModSim32軟件作為從機(jī),MODSCAN32軟件作為主機(jī)。

基于Qt的Modbus從機(jī)程序

有了上面的演示,我們知道了主機(jī)發(fā)送不同功能碼的時(shí)候,我們應(yīng)該返回給主機(jī)什么樣的數(shù)據(jù)內(nèi)容,下面我們?cè)谥拔覀兎窒淼摹?使用Qt打造屬于自己的串口調(diào)試助手 》的基礎(chǔ)上,完成0x03和0x06功能碼的應(yīng)答,最終程序的界面顯示如下。

因?yàn)镸odbus協(xié)議是主從模式,從機(jī)不會(huì)主動(dòng)發(fā)數(shù)據(jù)包至主機(jī),從機(jī)只要解析接收到的數(shù)據(jù)包,然后根據(jù)協(xié)議規(guī)定返回對(duì)應(yīng)的內(nèi)容即可。

所以我們的Qt程序,主要工作就是解析收到的串口數(shù)據(jù),因此,在串口接收函數(shù)中,解析收到的數(shù)據(jù)包具體需要做如下工作:

將接收到的前6個(gè)字節(jié)數(shù)據(jù)進(jìn)行CRC計(jì)算;

CRC計(jì)算的結(jié)果跟接收到的第7、第8字節(jié)比較,如果一致,證明數(shù)據(jù)包沒(méi)有問(wèn)題;

如果CRC正確,那么根據(jù)接收到的第2字節(jié)進(jìn)行判斷,當(dāng)?shù)?字節(jié)為0x03時(shí),為Modbus讀寄存器的操作;當(dāng)?shù)?字節(jié)為0x06時(shí),為Modbus寫(xiě)單寄存器的操作;

如果功能碼為0x03,則獲取TableView第2列內(nèi)的所有數(shù)據(jù),作為返回?cái)?shù)據(jù)包的寄存器值,然后將地址位、功能碼、數(shù)據(jù)長(zhǎng)度、寄存器值這些進(jìn)行CRC校驗(yàn),然后組成一個(gè)數(shù)據(jù)包發(fā)送至主機(jī);

如果功能碼為0x06,則將收到數(shù)據(jù)包的數(shù)據(jù)位組成一個(gè)WORD類(lèi)型的整形數(shù),根據(jù)寄存器地址,將其賦值到TableView中對(duì)應(yīng)的單元格中。

Qt實(shí)現(xiàn)的Modbus從機(jī)程序大家可以參考本文提供的源碼。

總結(jié)

經(jīng)過(guò)我們這兩次Modbus協(xié)議的分享,大家可以試試其他功能碼的發(fā)送與應(yīng)答,自己隨意玩起吧。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

公眾號(hào)『嵌入式從0到1』,號(hào)主:程序員小哈,是一個(gè)軟硬件全棧開(kāi)發(fā)工程師(12年工作經(jīng)驗(yàn)的老司機(jī)),電子發(fā)燒友論壇鴻蒙版塊版主,公眾號(hào)內(nèi)容專(zhuān)注于嵌入式學(xué)習(xí)。堅(jiān)持原創(chuàng),寫(xiě)有圖、有視頻的保姆級(jí)教程文章,篇篇有干貨。做一個(gè)講清楚,說(shuō)明白,大家學(xué)得會(huì)的交流平臺(tái)。