中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

阿里云網(wǎng)站更換域名seo自然排名優(yōu)化

阿里云網(wǎng)站更換域名,seo自然排名優(yōu)化,云速建站怎么樣,網(wǎng)站建設(shè)企業(yè)文化目錄 一、引言 通信方式 優(yōu)勢 案例 常見問題及解決方法 二、單片機與 Qt 上位機的通信方式 (一)使用 QT 上位機和 STC 單片機實現(xiàn)串口通信 三、單片機 Qt 上位機的優(yōu)勢 (一)高效便捷的 USB 通信上位機解決方案 &#xf…

目錄

一、引言

通信方式

優(yōu)勢

案例

常見問題及解決方法

二、單片機與 Qt 上位機的通信方式

(一)使用 QT 上位機和 STC 單片機實現(xiàn)串口通信

三、單片機 Qt 上位機的優(yōu)勢

(一)高效便捷的 USB 通信上位機解決方案

(二)學(xué)習(xí)上位機軟件對 C 語言開發(fā)的啟示

(三)選擇 C# 還是 Qt 作為上位機開發(fā)工具

四、單片機 Qt 上位機案例

(一)簡單的串口上位機控制單片機 LED

(二)使用 QT 制作單片機 bootloader 上位機實現(xiàn) IAP

(三)QT 上位機 + STC 單片機實現(xiàn)串口通信

五、單片機 Qt 上位機常見問題及解決方法

(一)基于 Qt 的上位機制作過程中遇到的問題及解決 ——TCP 通訊的建立

(二)串口接收數(shù)據(jù)分包問題處理

(三)在使用 QT 制作上位機界面時,遇到的常見問題


一、引言

單片機與 Qt 上位機的結(jié)合在嵌入式系統(tǒng)開發(fā)中具有重要意義。Qt 作為一種強大的跨平臺圖形用戶界面開發(fā)框架,可以為單片機系統(tǒng)提供直觀、便捷的人機交互界面,實現(xiàn)對單片機的控制和數(shù)據(jù)監(jiān)測。本文將詳細介紹單片機與 Qt 上位機的通信方式、優(yōu)勢、案例以及常見問題及解決方法。

通信方式

單片機與 Qt 上位機之間的通信主要通過串口實現(xiàn)。串口通信是一種簡單、穩(wěn)定、可靠的通信方式,其原理是通過串口發(fā)送端口將數(shù)據(jù)轉(zhuǎn)換為串行數(shù)據(jù),并將其發(fā)送到接收端口,接收端口將接收到的串行數(shù)據(jù)還原成原始數(shù)據(jù)。在單片機與 Qt 上位機之間進行串口通信時,需要確定好使用的波特率、數(shù)據(jù)位、停止位和校驗位等參數(shù),以保證數(shù)據(jù)傳輸?shù)恼_性。

優(yōu)勢

  1. 強大的人機交互界面:Qt 上位機可以提供豐富的圖形界面和交互功能,使操作人員能夠直觀地了解單片機系統(tǒng)的運行狀態(tài),并進行方便的控制操作。
  1. 跨平臺性:Qt 支持多種操作系統(tǒng),使得開發(fā)的上位機軟件可以在不同的平臺上運行,提高了軟件的通用性和可移植性。
  1. 高效的數(shù)據(jù)處理能力:Qt 上位機可以利用計算機的強大計算能力,對從單片機接收到的數(shù)據(jù)進行快速處理和分析,為系統(tǒng)的決策提供支持。
  1. 易于開發(fā)和維護:Qt 提供了豐富的開發(fā)工具和庫函數(shù),使得上位機軟件的開發(fā)變得更加簡單和高效。同時,Qt 的良好封裝性和模塊化設(shè)計也使得軟件的維護更加容易。

案例

  1. QSerialPort 實現(xiàn)上位機和單片機串口通信模塊
    • 背景知識:項目需要上位機控制單片機執(zhí)行任務(wù),單片機會發(fā)送心跳包和任務(wù)指令到上位機,因此采用全雙工模式,使用 Qt 自帶 QSerialPort 實現(xiàn)。
    • 設(shè)計思路:將通信模塊的發(fā)送和數(shù)據(jù)接收實現(xiàn)在次線程,數(shù)據(jù)解析另起線程,處理數(shù)據(jù)后將處理結(jié)果發(fā)送到 UI 線程。UI 線程發(fā)送指令信號,次線程槽函數(shù)中將指令轉(zhuǎn)變?yōu)橥ㄐ艆f(xié)議數(shù)據(jù),放置于發(fā)送數(shù)據(jù)隊列,利用該線程中的定時器定時發(fā)送;QSeriealPort 接收數(shù)據(jù)的槽函數(shù)負責(zé)接收數(shù)據(jù),并在其實現(xiàn)內(nèi)將接收到的數(shù)據(jù)進行解析。設(shè)計了 DeviceManager、DeviceControl、DeviceDataRecete 三個類。
    • 調(diào)試運行:UI 線程通過 DeviceManager 發(fā)送任務(wù)命令信號,DeviceControl 在次線程中執(zhí)行命令轉(zhuǎn)換為通信協(xié)議數(shù)據(jù),通過定時進行發(fā)送,同時接收串口數(shù)據(jù),并在 DeviceControl 的接收槽函數(shù)的讀取并推入 DeviceDataRecete 的數(shù)據(jù)隊列,DeviceDataRecete 對數(shù)據(jù)進行解析,并將結(jié)果通過 DeviceControl 發(fā)送到 DeviceManager 所在的 UI 線程。
    • 結(jié)果分析:測試顯示可正常運行,該模式適合實時通信,在效率方面可以,DeviceDataRecete 線程可以使用條件變量。
  1. STM32 單片機如何處理 QT 上位機串口中發(fā)過來的數(shù)據(jù)?
    • 配置串口通信參數(shù):定義串口參數(shù)變量,設(shè)置串口的參數(shù),配置串口中斷。
    • 接收數(shù)據(jù):編寫串口接收數(shù)據(jù)的代碼,啟動串口接收中斷,每當(dāng)接收到一幀數(shù)據(jù)時,就會自動觸發(fā)回調(diào)函數(shù),并將接收到的數(shù)據(jù)存儲在 uart_rx_data 變量中。
    • 處理數(shù)據(jù):讀取接收緩沖區(qū)中的數(shù)據(jù),判斷接收到的數(shù)據(jù)類型,根據(jù)數(shù)據(jù)類型進行不同的操作。
    • 發(fā)送數(shù)據(jù):編寫串口發(fā)送數(shù)據(jù)的代碼,在需要發(fā)送數(shù)據(jù)時,調(diào)用串口發(fā)送函數(shù)即可。
  1. 串口接收數(shù)據(jù)分包問題處理(QT 上位機 / 單片機等)
    • 設(shè)計思路:數(shù)據(jù)的格式是頭 0XA4 0X4A,尾部是 0X3C 0X3C,里面包含數(shù)據(jù)數(shù)據(jù)長度和幀校驗等相關(guān)定義。采用每來一次數(shù)據(jù),識別當(dāng)前數(shù)據(jù)是否有尾部,如果有,則認為當(dāng)前數(shù)據(jù)是一包,則再將緩沖數(shù)據(jù)進行頭部識別,識別不到頭,證明是錯誤數(shù)據(jù),不進行處理。識別成功,則調(diào)用相應(yīng)處理函數(shù)。若數(shù)據(jù)中沒有尾部,則將數(shù)據(jù)放入緩存。若數(shù)據(jù)最后一位是 0X3C,則做好標(biāo)記,下一包數(shù)據(jù)來臨時優(yōu)先判斷第一個字節(jié)是不是 0X3C。若單次接收包含了多包數(shù)據(jù)也應(yīng)能處理。
    • 代碼參考:給出了 QT 代碼參考,包括多個函數(shù)的實現(xiàn),用于處理串口接收數(shù)據(jù)分包問題。
  1. qt 串口通信上位機遇到的問題
    • 問題描述:自己嘗試用 qt 寫了一個串口,可以接受數(shù)據(jù),但是發(fā)送數(shù)據(jù)的時候遇到了一點問題,發(fā)送時數(shù)據(jù)不能到單片機,但是在用 xcom 試的時候,之前在自己寫的串口上位機中發(fā)送的數(shù)據(jù)也會在 xcom 中顯示出來。
    • 可能原因及解決方法:檢查串口設(shè)置是否正確,包括波特率、數(shù)據(jù)位、校驗位、停止位等;確認數(shù)據(jù)格式是否正確,發(fā)送的數(shù)據(jù)格式是否與單片機接收的格式一致;檢查程序邏輯是否正確,針對程序整體進行調(diào)試和分析,確認程序邏輯是否有錯誤。同時給出了一個簡單的 Qt 串口通信上位機示例代碼。
  1. 【QT 自研上位機 與 ESP32 下位機聯(lián)調(diào)>>>串口控制 GPIO - 基礎(chǔ)樣例】
    • 概述:作為新手入門相關(guān)設(shè)備,打算出三章內(nèi)容,像之前調(diào)試 STM32 單片機一樣,本次第三章是和上位機進行聯(lián)合調(diào)試。包括串口基礎(chǔ)篇、結(jié)合 GPIO 進行外圍控制、與上位機聯(lián)合調(diào)試。
    • 實驗環(huán)境:介紹了 ESP32 的相關(guān)信息,包括芯片特點、硬件信息、調(diào)試環(huán)境等。
    • 自我總結(jié):有了調(diào)試串口和 IO 的經(jīng)驗,將兩者組合起來,就像學(xué)習(xí)東西一塊一塊學(xué),以小見大。同時提到了之前的聯(lián)合文章經(jīng)歷。
    • 實驗過程:驗證上位機 QT 程序,包括下載樣例代碼、修改 qt 程序、運行測試驗證;驗證下位機 ESP32 程序,包括下載樣例代碼、更改 ESP32 代碼,編譯下載、驗證;聯(lián)合調(diào)試 ESP32 和 qt 上位機,包括硬件連接、驗證。
    • 代碼連接和細節(jié)部分:給出了代碼連接,介紹了常見錯誤解決辦法、ESP32 工程下載后先清理、邏輯分析儀的使用等細節(jié)部分。
    • 總結(jié):總結(jié)了本次實驗的內(nèi)容和意義。
  1. 單片機真的不如上位機嗎?
    • 單片機和上位機在各自的領(lǐng)域都有著不可替代的作用,不能簡單地進行優(yōu)劣比較。單片機具有體積小、成本低、功耗低等特點,適合對尺寸和成本有嚴(yán)格限制的場合;上位機則憑借其更強大的計算能力和豐富的軟件資源,適用于需要大規(guī)模數(shù)據(jù)處理和復(fù)雜控制的場景。在實際應(yīng)用中,單片機和上位機通常是相輔相成的。
  1. 高效便捷:基于 QT 5 與 STM32 的 USB 通信上位機解決方案
    • 項目介紹:提供了一個基于 QT 5 的上位機程序,用于與 STM32 單片機進行 USB 通信。能夠?qū)崟r顯示從單片機發(fā)送的命令,實現(xiàn)高效的數(shù)據(jù)交互和監(jiān)控。
    • 項目技術(shù)分析:介紹了技術(shù)棧、技術(shù)優(yōu)勢和應(yīng)用場景。技術(shù)棧包括 QT 5、STM32 和 USB 通信;技術(shù)優(yōu)勢有實時性、易用性、兼容性;應(yīng)用場景包括嵌入式系統(tǒng)開發(fā)、物聯(lián)網(wǎng)設(shè)備調(diào)試和工業(yè)自動化控制。
    • 項目特點:高效通信、動態(tài)顯示、用戶友好、廣泛適用。
    • 結(jié)語:期待用戶的使用和反饋,共同推動技術(shù)的進一步發(fā)展。
  1. 基于 GD32E503 的直流數(shù)控電源
    • 作品設(shè)計:分為硬件設(shè)計和軟件設(shè)計,硬件設(shè)計主要分為 MCU 控制板模塊、DC-DC 模塊和快充模塊三個部分,軟件設(shè)計分為邏輯代碼的設(shè)計和上位機設(shè)計。上位機采用 QT 編寫,可以與 GD32 單片機進行交互,單片機將電壓、電流等信息通過串口發(fā)送給上位機,上位機進行接收并實時繪制動態(tài)波形。
    • 作品創(chuàng)新:具有恒壓、恒流輸出,紋波小,精度高,采用補償算法和中位值濾波算法減小誤差,做到了百分之百國產(chǎn)化替代,增加了快充、物聯(lián)網(wǎng)、存儲功能。
    • 測試分析:包括實物展示、性能測試、快充測試和獲獎評語。
  1. QT 上位機 + STC 單片機實現(xiàn)串口通信
    • 未詳細描述具體內(nèi)容。
  1. Qt5 實現(xiàn)與單片機 ATS89S51 通信
    • 測試環(huán)境:開發(fā)環(huán)境為 Qt5.96 Mingw32-bit 和 keil3。
    • 項目目標(biāo):實現(xiàn)下位機基于 STC 單片機控制 LED 燈模塊、獨立鍵盤模塊,實現(xiàn)基于 Qt 的上位機與下位機進行串口通信,通過上位機發(fā)送指令對下位機進行控制,并通過界面方式顯示。
    • 實現(xiàn)效果:展示了參數(shù)配置窗口、上位機控制界面等效果。
    • 關(guān)鍵通信類 QSerialport:介紹了這個類的作用和使用注意事項,給出了單片機參考代碼和上位機通信代碼的獲取方式。
  1. #4 使用 QT 制作單片機 bootloader 上位機實現(xiàn) IAP
    • QT 介紹:QT 是一個跨平臺的 C++ 圖形用戶界面庫,支持所有 Linux/Unix 系統(tǒng)和 Windows 平臺。開發(fā)上位機需要熟悉 QT 的基本操作、C++ 基礎(chǔ)語法等。
    • QT 分解 HEX 文件:介紹了 HEX 文件的格式含義和分解思路,給出了具體的代碼實現(xiàn),包括讀取和解析 HEX 文件、將 HEX 文件的每一行讀入二維數(shù)組、提取需要的信息、加入自定義指令等。

常見問題及解決方法

  1. 串口通信問題
    • 發(fā)送數(shù)據(jù)時數(shù)據(jù)不能到單片機:檢查串口設(shè)置是否正確,包括波特率、數(shù)據(jù)位、校驗位、停止位等;確認數(shù)據(jù)格式是否正確,發(fā)送的數(shù)據(jù)格式是否與單片機接收的格式一致;檢查程序邏輯是否正確,針對程序整體進行調(diào)試和分析,確認程序邏輯是否有錯誤。
    • 串口接收數(shù)據(jù)分包問題:采用合適的分包處理方法,如每來一次數(shù)據(jù),識別當(dāng)前數(shù)據(jù)是否有尾部,如果有,則認為當(dāng)前數(shù)據(jù)是一包,則再將緩沖數(shù)據(jù)進行頭部識別,識別不到頭,證明是錯誤數(shù)據(jù),不進行處理。識別成功,則調(diào)用相應(yīng)處理函數(shù)。若數(shù)據(jù)中沒有尾部,則將數(shù)據(jù)放入緩存。若數(shù)據(jù)最后一位是 0X3C,則做好標(biāo)記,下一包數(shù)據(jù)來臨時優(yōu)先判斷第一個字節(jié)是不是 0X3C。若單次接收包含了多包數(shù)據(jù)也應(yīng)能處理。
  1. 晶振頻率問題
    • 單片機的晶振頻率不是 11.0592MHz,導(dǎo)致發(fā)送信息出現(xiàn)誤差:使用串口誤差計算器計算,調(diào)整單片機的定時計數(shù)器的溢出值,確保上位機和單片機的波特率一致。
  1. 文件解析問題
    • 在使用 QT 制作單片機 bootloader 上位機實現(xiàn) IAP 時,分解 HEX 文件出現(xiàn)問題:理解 HEX 文件的格式含義,按照正確的思路進行文件解析,注意 QT 庫函數(shù)的作用,確保代碼正確實現(xiàn)。

二、單片機與 Qt 上位機的通信方式

(一)使用 QT 上位機和 STC 單片機實現(xiàn)串口通信

下位機完成數(shù)據(jù)生成和發(fā)送,上位機存儲和處理數(shù)據(jù)。通過光敏和熱敏傳感器進行 A/D 采集,將數(shù)據(jù)封裝成數(shù)據(jù)包發(fā)送到上位機。

在使用 QT 上位機和 STC 單片機進行串口通信時,通常采用以下步驟實現(xiàn):

1. 硬件連接

確保 STC 單片機與計算機正確連接,可以通過 USB 轉(zhuǎn)串口線等方式進行連接。

2. 配置串口參數(shù)

對于下位機 STC 單片機,需要進行串口配置。例如,設(shè)置串口工作方式、波特率、數(shù)據(jù)位、停止位和校驗位等。常見的配置如下:

 
void UsartConfiguration(){SCON = 0X50; // 設(shè)置為工作方式10101 0000TMOD = 0X20; // 設(shè)置計數(shù)器工作方式2PCON = 0X80; // 波特率加倍,波特率加倍加快傳輸速率但是如果232總線太長時有可能出現(xiàn)丟幀TH1 = 0XF4; // 計數(shù)器初始值設(shè)置,注意波特率是4800的TL1 = 0XF4;REN = 1; // 允許接受ES = 1; // 打開接收中斷EA = 1; // 打開總中斷TR1 = 1; // 打開計數(shù)器 T1}

對于上位機 QT,也需要配置相應(yīng)的串口參數(shù),確保與單片機的參數(shù)一致??梢酝ㄟ^以下方式設(shè)置:

 
m_serialPort = new QSerialPort();m_serialPort->setPortName("COM8");m_serialPort->setBaudRate(QSerialPort::Baud9600);m_serialPort->setDataBits(QSerialPort::Data8);m_serialPort->setParity(QSerialPort::NoParity);m_serialPort->setStopBits(QSerialPort::OneStop);m_serialPort->setFlowControl(QSerialPort::NoFlowControl);m_serialPort->setReadBufferSize(40960);m_serialPort->open(QIODevice::ReadWrite);

3. 數(shù)據(jù)發(fā)送與接收

下位機 STC 單片機可以通過以下方式發(fā)送數(shù)據(jù):

 
void Uart_Send_Byte(unsigned char uartData){SBUF = uartData;while(!TI);TI = 0;}上位機 QT 可以通過以下方式接收數(shù)據(jù):connect(ui->lineEdit, SIGNAL(editingFinished()), this, SLOT(send_data()));void Widget::send_data(){// 將數(shù)據(jù)轉(zhuǎn)換為 QByteArray 類型并發(fā)送uint8_t data_10 = ui->lineEdit->text().toInt();QString s = QString::number(data_10, 16);if(s.length() == 1){s = '0' + s;}QByteArray ba = QString2Hex(s);m_serialPort->write(ba);}

同時,上位機也可以通過定時器定時接收數(shù)據(jù),并進行數(shù)據(jù)解析。例如:

 
// 串口接收數(shù)據(jù)操作// 串口接收數(shù)據(jù)幀格式為:幀頭'*' 幀尾'#' 數(shù)字間間隔符號',' 符號全為英文格式void Widget::Read_Date(){int bufferlens = 0; // 幀長QString str = ui->Receive_text_window->toPlainText();timerserial->stop();QByteArray bufferbegin = "*"; // 幀頭int index = 0;QByteArray bufferend = "#"; // 幀尾int indexend = 0;QByteArray buffercashe;index = buffer.indexOf(bufferbegin, index); // 查找?guī)^indexend = buffer.indexOf(bufferend, indexend); // 查找?guī)瞚f((index < buffer.size()) && (indexend < buffer.size())){bufferlens = indexend - index + 1; // 計算幀長度buffercashe = buffer.mid(index, bufferlens); // 截取出數(shù)據(jù)幀}char recvdata[buffercashe.size()];memset(recvdata, 0, sizeof(recvdata));memcpy(recvdata, buffercashe.data(), bufferlens - 1);recvdata[buffercashe.size() - 1] = 35;if(recvdata[0] == '*' && recvdata[buffercashe.size() - 1] == '#') // 二次幀檢查{str_to_num(recvdata); // 更新數(shù)據(jù)并緩存到保存區(qū)str += "succeed:"; // 在文本窗口給出提示str += tr(buffercashe);str += " ";ui->Receive_text_window->clear();ui->Receive_text_window->append(str);}else{str += "error!";}}

4. 注意事項

在進行串口通信時,需要注意以下幾點:

  • 確保上位機和單片機的波特率一致。如果單片機的晶振頻率不是標(biāo)準(zhǔn)的 11.0592MHz,可能會導(dǎo)致發(fā)送信息出現(xiàn)誤差。此時可以使用串口誤差計算器計算,調(diào)整單片機的定時計數(shù)器的溢出值,確保上位機和單片機的波特率一致。
  • 注意數(shù)據(jù)格式的正確性。發(fā)送的數(shù)據(jù)格式應(yīng)與接收方的格式一致,避免出現(xiàn)數(shù)據(jù)解析錯誤。
  • 處理好串口接收數(shù)據(jù)分包問題。可以采用合適的分包處理方法,如每來一次數(shù)據(jù),識別當(dāng)前數(shù)據(jù)是否有尾部,如果有,則認為當(dāng)前數(shù)據(jù)是一包,則再將緩沖數(shù)據(jù)進行頭部識別,識別不到頭,證明是錯誤數(shù)據(jù),不進行處理。識別成功,則調(diào)用相應(yīng)處理函數(shù)。若數(shù)據(jù)中沒有尾部,則將數(shù)據(jù)放入緩存。若數(shù)據(jù)最后一位是 0X3C,則做好標(biāo)記,下一包數(shù)據(jù)來臨時優(yōu)先判斷第一個字節(jié)是不是 0X3C。若單次接收包含了多包數(shù)據(jù)也應(yīng)能處理。

三、單片機 Qt 上位機的優(yōu)勢

(一)高效便捷的 USB 通信上位機解決方案

基于 QT 5 與 STM32 的 USB 通信上位機具有諸多優(yōu)勢,能夠滿足多種場景需求。

1. 實時性:上位機能夠動態(tài)顯示從單片機發(fā)送的命令,確保數(shù)據(jù)的及時性和準(zhǔn)確性,讓用戶可以實時了解系統(tǒng)狀態(tài),便于及時做出決策和調(diào)整。

2. 易用性:QT 5 框架提供了直觀的用戶界面,操作簡單易行。即使是非專業(yè)人士也能輕松上手,降低了使用門檻,提高了工作效率。

3. 兼容性:支持多種 STM32 單片機型號,適應(yīng)不同的嵌入式系統(tǒng)需求。具有廣泛的適用性,無論是在嵌入式系統(tǒng)開發(fā)、物聯(lián)網(wǎng)設(shè)備調(diào)試還是工業(yè)自動化控制等領(lǐng)域,都能發(fā)揮重要作用。

4. 應(yīng)用場景廣泛

  • 在嵌入式系統(tǒng)開發(fā)過程中,開發(fā)者需要頻繁地與底層硬件進行交互。通過本上位機程序,開發(fā)者可以實時監(jiān)控單片機的狀態(tài),快速調(diào)試和優(yōu)化系統(tǒng)性能。
  • 物聯(lián)網(wǎng)設(shè)備的調(diào)試往往涉及大量的數(shù)據(jù)傳輸和監(jiān)控。本項目提供的 USB 通信解決方案,能夠幫助開發(fā)者高效地進行數(shù)據(jù)采集和分析,提升調(diào)試效率。
  • 在工業(yè)自動化控制領(lǐng)域,實時監(jiān)控和數(shù)據(jù)交互是確保系統(tǒng)穩(wěn)定運行的關(guān)鍵。通過本項目,工程師可以輕松實現(xiàn)對工業(yè)設(shè)備的遠程監(jiān)控和控制,提高生產(chǎn)效率。

(二)學(xué)習(xí)上位機軟件對 C 語言開發(fā)的啟示

上位機軟件的開發(fā)思路對 C 語言開發(fā)有很多啟示。

1. 展示強大的單片機軟件:上位機可以將強大的單片機軟件展示出來,讓用戶更直觀地了解系統(tǒng)的功能和性能。在工業(yè)自動化控制等場景中,上位機軟件能夠呈現(xiàn)出單片機系統(tǒng)的運行狀態(tài),方便用戶進行監(jiān)控和操作。

2. 方便軟件調(diào)試時讀寫參數(shù):在軟件調(diào)試過程中,上位機軟件可以提供便捷的參數(shù)讀寫功能。例如,當(dāng)進行運動控制軟件調(diào)試時,PID 參數(shù)可能需要在現(xiàn)場實時調(diào)整。如果使用上位機軟件,就可以輕松地修改參數(shù),無需一遍遍燒寫程序或通過調(diào)試軟件不斷地發(fā)協(xié)議,提高了調(diào)試效率。

3. 學(xué)習(xí)高級語言的面向?qū)ο笤O(shè)計思想:上位機開發(fā)總離不開學(xué)習(xí)高級語言,雖然很多做底層的人可能對高級語言有偏見,但不可否認的是,高級語言確實有很重要的思想在里面,其中 “面向?qū)ο蟆?的設(shè)計思想尤為重要。如果掌握了這種思想,并將其應(yīng)用于 C 語言的開發(fā)中,對 C 語言開發(fā)會非常有幫助。

(三)選擇 C# 還是 Qt 作為上位機開發(fā)工具

在選擇上位機開發(fā)工具時,需要考慮多個因素,根據(jù)具體需求和偏好做出選擇。

1. 跨平臺支持

  • 如果應(yīng)用程序需要在多個操作系統(tǒng)上運行,Qt 可能是更好的選擇。Qt 具有強大的跨平臺能力,可以幫助開發(fā)具備一致性和可移植性的應(yīng)用程序,適用于 Windows、Linux、macOS 等多個平臺。
  • C# 最初是為 Windows 平臺設(shè)計的,但隨著.NET Core 和.NET 5/6 的發(fā)布,現(xiàn)在也支持跨平臺開發(fā)。不過,在跨平臺支持方面,Qt 通常被認為做得更好。

2. GUI 開發(fā)

  • C# 擁有 Windows 窗體應(yīng)用程序和 WPF 等功能強大的 GUI 工具,可以快速構(gòu)建用戶界面。C# 語法簡潔,易于學(xué)習(xí)和使用,特別是對于.NET 框架的初學(xué)者。
  • Qt 則提供了豐富的 GUI 組件和工具包,可用于構(gòu)建漂亮且跨平臺的界面。Qt 的 QML 集成支持使用 QML 來構(gòu)建現(xiàn)代、動態(tài)的用戶界面,可以實現(xiàn)復(fù)雜的 UI 設(shè)計和動畫效果。

3. 學(xué)習(xí)曲線和經(jīng)驗

  • 如果你已經(jīng)熟悉 C# 或 C++,選擇相應(yīng)的框架可能更容易上手。如果你在 C# 或 C++ 中有特定的偏好或經(jīng)驗,可以根據(jù)自己的喜好選擇。
  • C# 語法簡潔,對于初學(xué)者來說可能更容易學(xué)習(xí)。而 Qt 使用 C++ 作為主要的編程語言,如果你對 C++ 比較熟悉,那么 Qt 可能更適合你。

4. 生態(tài)系統(tǒng)和資源

  • C# 和 Qt 都擁有龐大的開發(fā)者社區(qū)和豐富的資源??紤]查閱相關(guān)的教程、文檔和論壇,了解它們的生態(tài)系統(tǒng)和可用資源,這有助于你在學(xué)習(xí)和開發(fā)過程中獲得支持和幫助。
  • C# 在 Windows 平臺上有強大的 IDE 支持,如 Visual Studio,提供了智能感知、調(diào)試工具等功能。Qt 也有豐富的開發(fā)工具和庫函數(shù),以及詳細的文檔支持。

5. 性能要求

  • 如果你對性能有較高要求,C++ 通常比 C# 更接近底層,可能在某些情況下具有優(yōu)勢。Qt 使用 C++ 作為主要的編程語言,因此在性能方面可能更有優(yōu)勢。
  • 不過,在實際應(yīng)用中,性能差異可能并不明顯,具體取決于應(yīng)用程序的需求和使用場景。

綜上所述,選擇 C# 還是 Qt 作為上位機開發(fā)工具需要權(quán)衡以上因素,并根據(jù)具體需求和偏好做出選擇。你也可以考慮根據(jù)項目需要,綜合使用 C# 和 Qt,例如使用 C# 開發(fā) Windows 平臺上的應(yīng)用程序,或使用 Qt 進行跨平臺開發(fā)。

四、單片機 Qt 上位機案例

(一)簡單的串口上位機控制單片機 LED

學(xué) QT 時寫的一個簡單串口上位機,用來控制單片機上的 2 個 LED,一個只有開和關(guān)狀態(tài),一個可以調(diào)節(jié)亮度。

通過 Qt 的串口通信功能,可以實現(xiàn)與單片機的交互,從而控制 LED 的狀態(tài)。對于只有開和關(guān)狀態(tài)的 LED,可以通過發(fā)送特定的指令讓單片機控制其亮滅。對于可調(diào)節(jié)亮度的 LED,可以發(fā)送不同的指令來調(diào)整其亮度級別。

(二)使用 QT 制作單片機 bootloader 上位機實現(xiàn) IAP

QT 可用于開發(fā)跨平臺的上位機,介紹了 QT 分解 HEX 文件的方法以及與 MCU 的通信流程。

QT 是一個強大的 C++ 圖形用戶界面庫,支持多種操作系統(tǒng)。在開發(fā)單片機 bootloader 上位機實現(xiàn) IAP(In-Application Programming)時,首先需要熟悉 QT 的基本操作和 C++ 基礎(chǔ)語法。

QT 分解 HEX 文件時,先將 HEX 的每一行都讀入一個二維數(shù)組,一維是 HEX 數(shù)據(jù),二維是總的 HEX 行數(shù)。然后將不需要的數(shù)據(jù)刪掉,如冒號和最后兩位校驗碼,因為要加入自定義指令,所以用自己封裝的校驗函數(shù)計算校驗碼。接著將需要的信息,如地址段、data 長度和 data 都提取出來,順便再加入自定義指令。

在與 MCU 通信時,確定好通信格式,發(fā)送前加入自定義指令,并調(diào)用校驗函數(shù)計算出這一包的校驗和,發(fā)給 MCU。MCU 處理后提取出地址值和 data 段向 FLASH 寫入,當(dāng)最后一包寫完時 MCU 即可跳轉(zhuǎn) app。

(三)QT 上位機 + STC 單片機實現(xiàn)串口通信

第一個上位機小項目,實現(xiàn) QT 與 STC 單片機的串口通信,可讀取溫度等數(shù)據(jù)。

通過 Qt 的 serialport 模塊,可以實現(xiàn)與 STC 單片機的串口通信。下位機完成數(shù)據(jù)生成和發(fā)送,上位機存儲和處理數(shù)據(jù)。例如,可以通過光敏和熱敏傳感器進行 A/D 采集,將數(shù)據(jù)封裝成數(shù)據(jù)包發(fā)送到上位機。

在使用 QT 上位機和 STC 單片機進行串口通信時,需要進行硬件連接和配置串口參數(shù)。確保 STC 單片機與計算機正確連接,可以通過 USB 轉(zhuǎn)串口線等方式進行連接。對于下位機 STC 單片機,需要進行串口配置,設(shè)置串口工作方式、波特率、數(shù)據(jù)位、停止位和校驗位等。對于上位機 QT,也需要配置相應(yīng)的串口參數(shù),確保與單片機的參數(shù)一致。

數(shù)據(jù)發(fā)送與接收可以通過特定的函數(shù)實現(xiàn)。下位機 STC 單片機可以通過發(fā)送函數(shù)發(fā)送數(shù)據(jù),上位機 QT 可以通過接收函數(shù)接收數(shù)據(jù),并進行數(shù)據(jù)解析。同時,上位機也可以通過定時器定時接收數(shù)據(jù),并進行數(shù)據(jù)解析。

在進行串口通信時,需要注意確保上位機和單片機的波特率一致,注意數(shù)據(jù)格式的正確性,處理好串口接收數(shù)據(jù)分包問題。

五、單片機 Qt 上位機常見問題及解決方法

(一)基于 Qt 的上位機制作過程中遇到的問題及解決 ——TCP 通訊的建立

在進行基于 Qt 的上位機制作時,通訊協(xié)議的選擇至關(guān)重要。本部分將詳細講解 TCP 通訊的搭建過程,包括頭文件設(shè)置、UI 界面設(shè)計以及功能實現(xiàn)等方面。

1. 上位機功能與通訊協(xié)議選擇

該上位機可能用于多種場景,如工業(yè)控制、數(shù)據(jù)監(jiān)測等。在選擇通訊協(xié)議時,需要考慮數(shù)據(jù)傳輸?shù)目煽啃?、實時性以及系統(tǒng)的具體需求。一開始可能計劃使用 UDP 進行通訊,因為對于某些場景下的數(shù)據(jù)精度要求不高,UDP 協(xié)議相對更高效。然而,由于所使用的設(shè)備(如 LiDAR)型號可能不支持 UDP 連接方式,最后決定使用 TCP 進行通訊。

2. TCP 通訊的搭建

2.1 創(chuàng)建類

首先,對項目右鍵選擇 “添加新文件”,然后選擇 Qt 中的 Qt 設(shè)計器界面類,這里可以根據(jù)習(xí)慣選擇,比如選擇 Main Window。點擊下一步后,輸入類名時要注意命名規(guī)范,避免后續(xù)出現(xiàn)混淆。創(chuàng)建成功后會生成三個文件,分別是頭文件(.h)、源文件(.cpp)和界面文件(.ui)。

2.2 頭文件設(shè)置

進入頭文件,需要進行以下操作:

  • 引用必要的頭文件,如#include <QTcpSocket>,用于 TCP 套接字的操作。
  • 創(chuàng)建一個接收信息的函數(shù),函數(shù)名可以自定義,例如void receiveMessage(),用于接收 TCP 連接傳來的消息。
  • 建立一個指針變量QTcpSocket* TcpSocket,以便在后續(xù)的代碼中使用。

2.3 UI 界面

設(shè)計一個大致的 UI 界面,為了測試功能可以先簡單布局。在設(shè)計 UI 時,建議給每個控件起好對應(yīng)的名字,尤其是在創(chuàng)建槽函數(shù)之前,這樣可以避免在控件較多時出現(xiàn)混亂。

2.4 功能實現(xiàn)

2.4.1 建立連接

右鍵點擊建立連接的按鈕,選擇 “轉(zhuǎn)到槽”,選擇 “clicked ()” 信號并確定。這樣會生成一個由按鈕名字和 “_clicked” 組成的函數(shù),例如void tcpSocket::on_pushButton_buildConnect_clicked()。在這個函數(shù)中實現(xiàn)建立 TCP 連接的功能:

 
void tcpSocket::on_pushButton_buildConnect_clicked(){QString ipAddress = "192.168.0.1"; //雷達的 IP 地址quint16 port = 2112; //雷達的端口TcpSocket->connectToHost(ipAddress, port); //建立連接if (TcpSocket->waitForConnected(3000)) //等待連接,如果超時則連接失敗{qDebug() << "Connected to LiDAR";}else{qDebug() << "Failed to connect to LiDAR";}}

在實際使用中,可以先用其他方法驗證 IP 是否正確,例如在命令提示符中輸入 “ping 你要連接的 ip 地址”,如果能 ping 通表示可以連接,但實際連接時還要注意端口號,一般在雷達的官方文檔中有寫。

2.4.2 發(fā)送信息

和建立連接類似,右鍵點擊發(fā)送信息的按鈕,選擇 “轉(zhuǎn)到槽”,生成相應(yīng)的函數(shù)。在發(fā)送信息的函數(shù)中,從控件中讀取信息,進行必要的格式轉(zhuǎn)換后,使用TcpSocket->write()函數(shù)發(fā)送信息。

 
void tcpSocket::on_pushButton_send_clicked(){QString message = ui->textEdit_sendData->toPlainText(); //從控件中讀取信息// 去除空格和換行符message.remove(" ");message.remove("\n");// 將 HEX 字符串轉(zhuǎn)換為字節(jié)數(shù)組QByteArray hexData = QByteArray::fromHex(message.toUtf8());TcpSocket->write(hexData); //發(fā)送信息qDebug() << "發(fā)送指令(HEX):" << hexData.toHex(); //驗證}

2.4.3 接收信息

在主函數(shù)中添加以下代碼,建立readyRead信號和receiveMessage函數(shù)的連接,當(dāng)收到readyRead信號時,執(zhí)行receiveMessage函數(shù)。

 
connect(TcpSocket, &QTcpSocket::readyRead, this, &tcpSocket::receiveMessage);receiveMessage函數(shù)的代碼如下:void tcpSocket::receiveMessage(){// 讀取數(shù)據(jù)QByteArray response = TcpSocket->readAll();// 處理接收到的數(shù)據(jù)QString messageUTF = QString::fromUtf8(response);// 顯示在文本框中ui->textEdit_receiveData->append(messageUTF);}

(二)串口接收數(shù)據(jù)分包問題處理

在 QT 上位機、單片機等使用情況下,串口數(shù)據(jù)分包問題是一個常見的難題。本部分將介紹處理串口數(shù)據(jù)分包問題的思路和代碼參考。

1. 設(shè)計思路

數(shù)據(jù)的格式通常有特定的頭尾標(biāo)志,例如頭為 0XA4 0X4A,尾部是 0X3C 0X3C,里面還包含數(shù)據(jù)長度和幀校驗等相關(guān)定義。處理思路如下:

  • 每來一次數(shù)據(jù),識別當(dāng)前數(shù)據(jù)是否有尾部,如果有,則認為當(dāng)前數(shù)據(jù)是一包,則再將緩沖數(shù)據(jù)進行頭部識別。識別不到頭,證明是錯誤數(shù)據(jù),不進行處理。識別成功,則調(diào)用相應(yīng)處理函數(shù)。
  • 若數(shù)據(jù)中沒有尾部,則將數(shù)據(jù)放入緩存。若數(shù)據(jù)最后一位是 0X3C,則做好標(biāo)記,下一包數(shù)據(jù)來臨時優(yōu)先判斷第一個字節(jié)是不是 0X3C。
  • 若單次接收包含了多包數(shù)據(jù)也應(yīng)能處理。

2. 代碼參考

以下是 QT 代碼參考:

 
class MainWindow:public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();void setupPlot();void setCVMode();void setCCMode();void initActionsConnections();private slots:void updateView();void updateLCDNumber();void handleTimeout();void showStatusMessage(const QString &message);void about();void openSerialPort();void closeSerialPort();void writeData(const QByteArray &data);void readData();void SerialRecv_solt();void process_serial_recv(char*pBuf,int len);void ComSend(unsigned char cmd1,int var1);int get_tail(unsigned char*pbuf,int len);int get_head(unsigned char*pbuf,int len);int send_copy_from_read(unsigned char*pbuf,int len);int process_pack(unsigned char* pbuf,int len);void on_doubleSpinBox_vol_valueChanged(double arg1);void on_doubleSpinBox_cur_valueChanged(double arg1);void on_radioButton_cv_clicked();void on_radioButton_cc_clicked();void on_pushButton_verify_clicked();void on_verticalSlider_vol_valueChanged(int value);void on_verticalSlider_cur_valueChanged(int value);void on_actionCtrl_triggered(bool checked);void on_actionUpdate_triggered();private:Ui::MainWindow *ui;QSerialPort *serial;SettingsDialog *settings;QVector<double> vol, cur;QTimer *m_pTimer;unsigned char data_recv[1024];int len_pack=0;int maybe_tail;};int MainWindow::get_tail(unsigned char*pbuf,int len){int i=0;int pos;for(i=0;i<len;i++){if(pbuf[i]==0xc3){if(i==(len-1)){return 0; //疑似拿到了尾部一個字節(jié)}else{if(pbuf[i+1]==0xc3)pos=i+2; //第幾個字節(jié)出現(xiàn)了尾部return pos; //完整的拿到了尾部}}}return -1; //沒有拿到尾部任何信息}int MainWindow::get_head(unsigned char*pbuf,int len){int i=0;for(i=0;i<len;i++){if((pbuf[i]==0xA5)&&(i<(len-1))){if(pbuf[i+1]==0x5A)return i;}}return -1; //沒有頭部信息}int MainWindow::process_pack(unsigned char* pbuf,int len){int pos_head=0;memcpy(data_recv+len_pack,pbuf,len);len_pack+=len;pos_head=get_head(data_recv,len_pack);if(pos_head>=0) //找到了頭{send_copy_from_read(data_recv+pos_head,len_pack-pos_head);qDebug() << "hello";}//相關(guān)標(biāo)志位清零maybe_tail=0;len_pack=0;}void MainWindow::SerialRecv_solt(){QByteArray data;data.resize(serial->bytesAvailable());serial->read(data.data(),data.size());int size_now=0;int pos_data=0;int data_num=0;size_now=data.size();if((maybe_tail==1)&&((unsigned char)data.data()[0]==0xc3)) //識別到結(jié)束位{process_pack((unsigned char*)data.data(),1); //將當(dāng)前包剩余的數(shù)據(jù)賦值給下一包if(data.size()>1){memcpy(data_recv+len_pack,&data.data()[1],(data.size()-1));len_pack+=(data.size()-1);}}else{maybe_tail=0;size_now--;while(size_now>0){pos_data=data.size()-size_now;data_num=get_tail((unsigned char*)data.data()+pos_data,size_now);if(data_num>0) //識別到結(jié)束位{process_pack((unsigned char*)data.data()+pos_data,data_num);size_now=data.size()-data_num;}else //沒有識別到結(jié)束位{if(data_num==0)maybe_tail=1;if((len_pack+data.size())<1024) //限制緩沖大小為 1024 個字節(jié){memcpy(data_recv+len_pack,data.data()+pos_data,size_now);len_pack+=size_now;}else{len_pack=0; //從頭開始}break;}}}}

(三)在使用 QT 制作上位機界面時,遇到的常見問題

在使用 QT 制作上位機界面時,可能會遇到一些常見問題,本部分將針對這些問題進行分析并提供解決方法。

1. 實現(xiàn)上位機界面可拖拽變大變小功能

  • 使用布局功能,這些布局功能可嵌套使用。
  • 在布局功能的基礎(chǔ)上,若想讓控件排列整齊,可以在控件間放置特定控件,在屬性界面設(shè)置高和寬,從而達到對齊效果。
  • 布局完畢后,在對象或 UI 設(shè)計界面右鍵選中最外圍控件,選擇布局 -> 柵格布局。運行生成的界面就可以使用鼠標(biāo)拖拽功能來改變上位機界面的大小了。
  • 若想控件大小自適應(yīng),可以在屬性中,將 sizePolicy 中的水平策略與垂直策略設(shè)置成 Expanding,在設(shè)計一個最小尺寸與最大尺寸。

2. 解決最大化按鈕灰色問題

在 Qt Designer 中將 maximumSize 的值設(shè)置為 16777215x16777215 即可使窗口打開時最大化按鈕可用。具體代碼如下:

 

const QSize MAIN_SIZE_MAX = QSize(16777215,16777215);

this->setMaximumSize(MAIN_SIZE_MAX);

this->setWindowFlag(Qt::WindowMaximizeButtonHint, true);

3. 處理不同分辨率電腦顯示效果差異問題

在 QT 的 main 函數(shù)中,在 “QApplication a (argc, argv);” 之前加上如下幾句語句,即可實現(xiàn) QT 上位機軟件適配不同分辨率的電腦。

 

QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);

QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);

QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);

4. 給圖像添加圖標(biāo)

  • 首先選擇一張圖片,將其轉(zhuǎn)化為.ico 文件,可以通過在線工具進行轉(zhuǎn)化。
  • 右鍵選中項目 ->Add New,選擇 Qt Resource File,生成一個.qrc 文件。點擊 Add Prefix,會在下面生成一個文件,在屬性的前綴處可修改路徑。然后點擊 Add Files 將.ico 圖標(biāo)添加進來。上位機界面的其他控件的圖標(biāo)(如菜單欄、工具欄里的圖標(biāo)),也可以放到這個位置。
  • 在程序中,添加如下程序:setWindowIcon(QIcon(":/icon/logo.ico")),并在當(dāng)前項目目錄下創(chuàng)建一個.rc 結(jié)尾的文件,在該文件中輸入IDI_ICON1 ICON DISCARDABLE "logo.ico"。在該項目的.pro 文件里,添加RC_FILE += logo.rc
http://m.risenshineclean.com/news/66239.html

相關(guān)文章:

  • 企業(yè)手機網(wǎng)站建設(shè)方案千牛怎么做免費推廣引流
  • 網(wǎng)站備案 名稱 不一致網(wǎng)站推廣seo是什么
  • 建設(shè)網(wǎng)站程序下載凡科建站后屬于自己的網(wǎng)站嗎
  • 建站平臺 做網(wǎng)站網(wǎng)絡(luò)營銷服務(wù)的特點有哪些
  • 企業(yè)建站多站點管理系統(tǒng)惠州seo排名公司
  • 黃岡貼吧黃岡論壇吧今日頭條seo
  • 長沙哪個平臺做網(wǎng)站好滄州seo公司
  • 云南個舊建設(shè)局網(wǎng)站深圳營銷型網(wǎng)站定制
  • 公司網(wǎng)站怎么做店鋪seo是什么意思
  • 重慶做營銷型網(wǎng)站建設(shè)公司關(guān)鍵詞優(yōu)化一年的收費標(biāo)準(zhǔn)
  • 商業(yè)網(wǎng)站建設(shè)案例教程seo是干什么的
  • 怎么制作網(wǎng)站客服百度網(wǎng)頁版鏈接地址
  • 網(wǎng)站建設(shè)報價單表格深圳網(wǎng)站seo推廣
  • 做網(wǎng)站的人怎么上傳內(nèi)容的湖南網(wǎng)站建站系統(tǒng)哪家好
  • 溫州網(wǎng)站建設(shè)方案報價seo優(yōu)化排名易下拉用法
  • 四川省網(wǎng)站建設(shè)百度網(wǎng)頁打不開
  • 建筑工程信息頻道寧波受歡迎全網(wǎng)seo優(yōu)化
  • 網(wǎng)站開發(fā)php怎么樣百度推廣代理商加盟
  • wordpress菜譜網(wǎng)站站長之家ip地址查詢
  • github 建網(wǎng)站行業(yè)網(wǎng)站有哪些平臺
  • 網(wǎng)站怎么做播放器促銷活動推廣語言
  • 設(shè)計素材網(wǎng)站源碼seo谷歌外貿(mào)推廣
  • 自己的簡歷網(wǎng)站怎么做百度收錄查詢工具官網(wǎng)
  • 做網(wǎng)站建設(shè)的電話銷售免費建立網(wǎng)站
  • 網(wǎng)站服務(wù)器要多少錢南寧推廣軟件
  • 做電氣設(shè)計有哪些好的網(wǎng)站四川省人民政府官網(wǎng)
  • 網(wǎng)站首頁不被收錄上海廣告公司
  • 香港公司能在國內(nèi)做網(wǎng)站個人免費網(wǎng)上注冊公司
  • 企業(yè)網(wǎng)站的建設(shè)流程南昌seo數(shù)據(jù)監(jiān)控
  • 帝國cms怎么做網(wǎng)站谷歌ads