QT串列埠通訊(1)
最近幫老師做的專案中使用到了QT串列埠,然後首先百度了一下,發現網上的QT串列埠程式碼都是同一個版本。而且沒有公開原始碼,遂自己寫了個簡單的串列埠通訊程式碼,並將它公佈出來,一方面供有需要的人蔘考,另一方面記錄下來,也可以防止自己忘記了。
本專案沒有用到QT自帶的串列埠通訊模組,使用了第三方庫qextserialport,這個庫基本已經滿足了串列埠所有的功能,而且上手也快。好了。廢話不多說了,先來張效果圖吧。
這是整體效果圖,主要實現的是開發板和下位機通訊,上位機通過串列埠傳送指令給下位機,下位機再執行相應的操作。本文主要講講串列埠通訊的部分吧。
簡單來說,串列埠通訊分為三部分:1:設定埠號和波特率等等,資料位和校驗之類的一般的可以提前設定好,再程式碼中同樣也可以設定。2:將資料寫入串列埠,這個時候就要分發送的是多少進位制的資料了,雖然計算機在實際儲存時是不區分進位制的。3:讀串列埠資料,將串列埠接收到的資料讀出來,進行下一步處理。後面我會把全部程式碼貼出來,程式碼經過除錯已經可以運行了。本文中具體的控制元件佈局我就不講了,我只講講一些核心的程式碼,大家感興趣的話可以自己去跑跑我的程式碼,程式碼中註釋非常詳細,每一行都有註釋,看起來不費勁。
設定埠和波特率
//開啟串列埠,波特率和埠號可以通過下拉選單進行選擇 void uwiCMonitorPC::on_openMyComBtn_clicked() { QString portName = portNameComboBox->currentText(); //獲取串列埠名 myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven); //定義串列埠物件,並傳遞引數,在建構函式裡對其進行初始化 myCom ->open(QIODevice::ReadWrite); //開啟串列埠 if(baudRateComboBox->currentText()==tr("38400")) //根據下拉選單中內容對串列埠進行設定 //設定波特率 myCom->setBaudRate(BAUD38400); else if(baudRateComboBox->currentText()==tr("115200")) myCom->setBaudRate(BAUD115200); //設定資料位 myCom->setDataBits(DATA_8); //設定奇偶校驗 myCom->setParity(PAR_NONE); //設定停止位 myCom->setStopBits(STOP_1); myCom->setFlowControl(FLOW_OFF); //設定資料流控制,我們使用無資料流控制的預設設定 myCom->setTimeout(500); //設定延時 connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); //訊號和槽函式關聯,當串列埠緩衝區有資料時,進行讀串列埠操作 openMyComBtn->setEnabled(false); //開啟串列埠後“開啟串列埠”按鈕不可用 closeMyComBtn->setEnabled(true); //開啟串列埠後“關閉串列埠”按鈕可用 sendMsgBtn->setEnabled(true); //開啟串列埠後“傳送資料”按鈕可用 O2U1->setEnabled(true); O2U2->setEnabled(true); O2U3->setEnabled(true); baudRateComboBox->setEnabled(false); //設定各個組合框不可用 portNameComboBox->setEnabled(false); }
在埠設定和波特率配置中,主要用到的控制元件有QComboBox,可以實現下拉選單功能,還沒用過這個控制元件的小夥伴可以自行百度下,很簡單的啦。
寫串列埠資料
//傳送訊息 void uwiCMonitorPC::on_sendMsgBtn_clicked() { if(O2U1->isChecked()||O2U2->isChecked()||O2U3->isChecked())//判斷選擇的是那種功能 { QString num; if(O2U1->isChecked())//配置查詢 { int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x0d,0x01,0x00,0x00,0x00,0x00}; int *p=table; int wCRC =CRC16(p,11); table[11]=wCRC>>8; table[12]=wCRC&0x00ff; for(int i=0;i<13;i++) num+=table[i]; } else if(O2U2->isChecked())//地址配置 { int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x11,0x02,0x00,0x00,0x00,0x00,0x00,0x0c,0x01,0x02}; table[11]=edit1->text().toInt(); int *p=table; int wCRC =CRC16(p,15); table[15]=wCRC>>8; table[16]=wCRC&0x00ff; for(int i=0;i<17;i++) num+=table[i]; } else if(O2U3->isChecked())//功能配置 { int table[20]={0x2e,0x2d,0x3d,0x3e,0x00,0x0e,0x03,0x00,0x00,0x00}; if(device->currentText()==tr("投料機")) table[10]=0x01; else if(device->currentText()==tr("增氧泵")) table[10]=0x02; else if(device->currentText()==tr("三合一")) table[10]=0x03; else if(device->currentText()==tr("氨 氮")) table[10]=0x04; else if(device->currentText()==tr("氣象站")) table[10]=0x05; else if(device->currentText()==tr("三合一和氨氮")) table[10]=0x06; else table[10]=0x07; table[11]=edit5->text().toInt(); int *p=table; int wCRC =CRC16(p,12); table[12]=wCRC>>8; table[13]=wCRC&0x00ff; for(int i=0;i<14;i++) num+=table[i]; } QByteArray outData=num.toAscii();//將16進位制數轉化為可以傳送的QByteArray 資料 myCom->write(outData);//將資料寫入串列埠 }
資料格式轉換真心累啊,我在後面中會給大家介紹我在資料格式轉換中遇到的坑,大家可以參考,寫入資料部分,其實最主要的控制元件就是一個lineedit,也即文字框,將要傳送的資料輸入到文字框,然後讀取文字框中的內容即可 table[11]=edit1->text().toInt();將edit1中輸入的內容轉換成10進位制,並存貯在table中,然後就可以寫入串列埠了,當然怎麼寫入的我們就可以不用管了,你只要負責把資料準備好就可以了,直接送到函式 myCom->write(outData);中就可以了,呼叫了第三方庫,很多步驟我們都省了。
讀串列埠資料
if (myCom->bytesAvailable()<=0)
{return;}//如果沒有收到資料就返回
Sleep(100);//延時100ms確保資料可以一次讀出
QByteArray temp = myCom->readAll();//得到全部資料
QString tempDataHex=uwiCMonitorPC::ByteArrayToHexStr(temp);//位元組陣列變為字串
textBrowser->insertPlainText(tempDataHex+"\n"); //返回資料顯示
讀串列埠部分也就是一個函式 myCom->readAll();讀之前需要延時一段時間以確保串列埠資料可以一次接受完成。將得到的資料轉換為QString型別,然後就可以送進去顯示了。
串列埠通訊主要的核心部分大概就是這三部分了,呼叫第三方庫,主要難點就在於資料型別轉換,因為串列埠傳送和文字框接受顯示的資料型別是不一樣的,還有傳送16進位制資料時也得進行資料型別轉換。反正我在格式轉換上面花了很多時間,我在下篇部落格中會貼出各種格式轉換的程式碼,供大家參考。
對串列埠通訊原理不瞭解的可以自己先去網上自行了解下原理,等了解原理後再寫串列埠程式就遊潤有餘了,整個程式碼我已經打包好了,只要用cmake編譯下就可以運行了(所有的控制元件都是用程式碼實現的,沒有基於qt caeater,控制元件不是拖拽來的,當然為了學習,為了提高程式碼能力,我建議不拖拽,如果在實際專案中那就不一樣了),我過會會將所有程式碼上傳,有問題的歡迎留言討論。
關於我自己
-
一個正派但不正經的程式設計師
-
18年計算機專業碩士畢業生,騰訊SNG部門實習生,現加盟快手科技 ,後端研發工程師一枚
-
喜歡技術,喜歡網際網路
-
民遙控 ,趙雷、陳粒、宋冬野
-
公眾號:程式設計美學,時不時寫篇文章,偶爾數羊,其實說到底,只是想和你聊聊