關(guān)于QT串口通信的一點理解

最近幫老師做的項目中使用到了QT串口筒扒,然后首先百度了一下您市,發(fā)現(xiàn)網(wǎng)上的QT串口代碼都是同一個版本。而且沒有公開源代碼,遂自己寫了個簡單的串口通信代碼翘单,并將它公布出來,一方面供有需要的人參考岭埠,另一方面記錄下來脆丁,也可以防止自己忘記了。

本項目沒有用到QT自帶的串口通信模塊稚叹,使用了第三方庫qextserialport焰薄,這個庫基本已經(jīng)滿足了串口所有的功能拿诸,而且上手也快。好了塞茅。廢話不多說了亩码,先來張效果圖吧。


這是整體效果圖野瘦,主要實現(xiàn)的是開發(fā)板和下位機通信描沟,上位機通過串口發(fā)送指令給下位機,下位機再執(zhí)行相應(yīng)的操作鞭光。本文主要講講串口通信的部分吧吏廉。

簡單來說,串口通信分為三部分:1:設(shè)置端口號和波特率等等惰许,數(shù)據(jù)位和校驗之類的一般的可以提前設(shè)定好席覆,再代碼中同樣也可以設(shè)定。2:將數(shù)據(jù)寫入串口汹买,這個時候就要分發(fā)送的是多少進(jìn)制的數(shù)據(jù)了佩伤,雖然計算機在實際存儲時是不區(qū)分進(jìn)制的。3:讀串口數(shù)據(jù)晦毙,將串口接收到的數(shù)據(jù)讀出來生巡,進(jìn)行下一步處理。后面我會把全部代碼貼出來结序,代碼經(jīng)過調(diào)試已經(jīng)可以運行了障斋。本文中具體的控件布局我就不講了,我只講講一些核心的代碼徐鹤,大家感興趣的話可以自己去跑跑我的代碼垃环,代碼中注釋非常詳細(xì),每一行都有注釋返敬,看起來不費勁遂庄。

1.設(shè)置端口和波特率

//打開串口,波特率和端口號可以通過下拉菜單進(jìn)行選擇
void uwiCMonitorPC::on_openMyComBtn_clicked()
{
    QString portName = portNameComboBox->currentText(); //獲取串口名
    myCom = new Win_QextSerialPort(portName,QextSerialBase::EventDriven);
    //定義串口對象劲赠,并傳遞參數(shù)涛目,在構(gòu)造函數(shù)里對其進(jìn)行初始化
    myCom ->open(QIODevice::ReadWrite); //打開串口
    if(baudRateComboBox->currentText()==tr("38400")) //根據(jù)下拉菜單中內(nèi)容對串口進(jìn)行設(shè)置
    //設(shè)置波特率
    myCom->setBaudRate(BAUD38400);
    else if(baudRateComboBox->currentText()==tr("115200"))
    myCom->setBaudRate(BAUD115200);
    //設(shè)置數(shù)據(jù)位
    myCom->setDataBits(DATA_8);
    //設(shè)置奇偶校驗
    myCom->setParity(PAR_NONE);
    //設(shè)置停止位 
    myCom->setStopBits(STOP_1);    
    myCom->setFlowControl(FLOW_OFF);  //設(shè)置數(shù)據(jù)流控制,我們使用無數(shù)據(jù)流控制的默認(rèn)設(shè)置
    myCom->setTimeout(500);  //設(shè)置延時
    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
    //信號和槽函數(shù)關(guān)聯(lián)凛澎,當(dāng)串口緩沖區(qū)有數(shù)據(jù)時霹肝,進(jìn)行讀串口操作
    openMyComBtn->setEnabled(false); //打開串口后“打開串口”按鈕不可用
    closeMyComBtn->setEnabled(true); //打開串口后“關(guān)閉串口”按鈕可用
    sendMsgBtn->setEnabled(true); //打開串口后“發(fā)送數(shù)據(jù)”按鈕可用
    O2U1->setEnabled(true);
    O2U2->setEnabled(true);
    O2U3->setEnabled(true);
    baudRateComboBox->setEnabled(false); //設(shè)置各個組合框不可用
    portNameComboBox->setEnabled(false);
}

在端口設(shè)置和波特率配置中,主要用到的控件有QComboBox塑煎,可以實現(xiàn)下拉菜單功能沫换,還沒用過這個控件的小伙伴可以自行百度下,很簡單的啦最铁。

2.寫串口數(shù)據(jù)

//發(fā)送消息
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進(jìn)制數(shù)轉(zhuǎn)化為可以發(fā)送的QByteArray 數(shù)據(jù)
    myCom->write(outData);//將數(shù)據(jù)寫入串口
}

數(shù)據(jù)格式轉(zhuǎn)換真心累啊讯赏,我在后面中會給大家介紹我在數(shù)據(jù)格式轉(zhuǎn)換中遇到的坑垮兑,大家可以參考,寫入數(shù)據(jù)部分漱挎,其實最主要的控件就是一個lineedit系枪,也即文本框,將要發(fā)送的數(shù)據(jù)輸入到文本框磕谅,然后讀取文本框中的內(nèi)容即可 table[11]=edit1->text().toInt();將edit1中輸入的內(nèi)容轉(zhuǎn)換成10進(jìn)制私爷,并存貯在table中,然后就可以寫入串口了怜庸,當(dāng)然怎么寫入的我們就可以不用管了当犯,你只要負(fù)責(zé)把數(shù)據(jù)準(zhǔn)備好就可以了,直接送到函數(shù) myCom->write(outData);中就可以了割疾,調(diào)用了第三方庫,很多步驟我們都省了嘉栓。

3.讀串口數(shù)據(jù)

if (myCom->bytesAvailable()<=0)
{return;}//如果沒有收到數(shù)據(jù)就返回
    Sleep(100);//延時100ms確保數(shù)據(jù)可以一次讀出
    QByteArray temp = myCom->readAll();//得到全部數(shù)據(jù)
    QString tempDataHex=uwiCMonitorPC::ByteArrayToHexStr(temp);//字節(jié)數(shù)組變?yōu)樽址?    textBrowser->insertPlainText(tempDataHex+"\n"); //返回數(shù)據(jù)顯示

讀串口部分也就是一個函數(shù) myCom->readAll();讀之前需要延時一段時間以確保串口數(shù)據(jù)可以一次接受完成宏榕。將得到的數(shù)據(jù)轉(zhuǎn)換為QString類型,然后就可以送進(jìn)去顯示了侵佃。

串口通信主要的核心部分大概就是這三部分了,調(diào)用第三方庫麻昼,主要難點就在于數(shù)據(jù)類型轉(zhuǎn)換,因為串口發(fā)送和文本框接受顯示的數(shù)據(jù)類型是不一樣的馋辈,還有發(fā)送16進(jìn)制數(shù)據(jù)時也得進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換抚芦。反正我在格式轉(zhuǎn)換上面花了很多時間,我在下篇博客中會貼出各種格式轉(zhuǎn)換的代碼迈螟,供大家參考叉抡。

對串口通信原理不了解的可以自己先去網(wǎng)上自行了解下原理,等了解原理后再寫串口程序就游潤有余了答毫,整個代碼我已經(jīng)打包好了褥民,只要用cmake編譯下就可以運行了(所有的控件都是用代碼實現(xiàn)的,沒有基于qt caeater洗搂,控件不是拖拽來的消返,當(dāng)然為了學(xué)習(xí),為了提高代碼能力耘拇,我建議不拖拽撵颊,如果在實際項目中那就不一樣了),我過會會將所有代碼上傳惫叛,有問題的歡迎留言討論倡勇。


關(guān)于我自己

一個正派但不正經(jīng)的程序員

  • 18年計算機專業(yè)碩士畢業(yè)生,騰訊SNG部門實習(xí)生挣棕,現(xiàn)加盟快手科技 译隘,后端研發(fā)工程師一枚

  • 喜歡技術(shù)亲桥,喜歡互聯(lián)網(wǎng)

  • 民遙控 ,趙雷固耘、陳粒题篷、宋冬野

  • 時不時寫篇文章,偶爾數(shù)羊厅目,其實說到底番枚,只是想和你聊聊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市损敷,隨后出現(xiàn)的幾起案子葫笼,更是在濱河造成了極大的恐慌,老刑警劉巖拗馒,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件路星,死亡現(xiàn)場離奇詭異,居然都是意外死亡诱桂,警方通過查閱死者的電腦和手機洋丐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挥等,“玉大人友绝,你說我怎么就攤上這事「尉ⅲ” “怎么了迁客?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辞槐。 經(jīng)常有香客問我掷漱,道長,這世上最難降的妖魔是什么催蝗? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任切威,我火速辦了婚禮,結(jié)果婚禮上丙号,老公的妹妹穿的比我還像新娘先朦。我一直安慰自己,他們只是感情好犬缨,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布喳魏。 她就那樣靜靜地躺著,像睡著了一般怀薛。 火紅的嫁衣襯著肌膚如雪刺彩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音创倔,去河邊找鬼嗡害。 笑死,一個胖子當(dāng)著我的面吹牛畦攘,可吹牛的內(nèi)容都是我干的霸妹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼知押,長吁一口氣:“原來是場噩夢啊……” “哼叹螟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起台盯,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤罢绽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后静盅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體良价,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年温亲,在試婚紗的時候發(fā)現(xiàn)自己被綠了棚壁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡栈虚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出史隆,到底是詐尸還是另有隱情魂务,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布泌射,位于F島的核電站粘姜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏熔酷。R本人自食惡果不足惜孤紧,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拒秘。 院中可真熱鬧号显,春花似錦、人聲如沸躺酒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽羹应。三九已至揽碘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雳刺。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工劫灶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掖桦。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓本昏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親滞详。 傳聞我的和親對象是個殘疾皇子凛俱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 姓名:莫益彰 學(xué)號:16030140019 【嵌牛導(dǎo)讀】:串口通信是指外設(shè)和計算機間,通過數(shù)據(jù)信號線 料饥、地線蒲犬、控制...
    換個名字消消毒閱讀 1,578評論 1 5
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,513評論 25 707
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料岸啡? 從這篇文章中你...
    hw1212閱讀 12,693評論 2 59
  • 茶靡花開原叮,陌路之美。 孤首望河畔巡蘸,夕陽斜下奋隶,不知離人淚。 心中難緬舊時光悦荒,杯中清酒一飲盡唯欣。 飛鴿...
    a36e8aaff5a5閱讀 458評論 0 0
  • 文/逐夢水鄉(xiāng) 前幾天碰纬,寫的一篇《來萍聊,考考你,這道題的答案是多少》悦析,寥寥幾百字寿桨,閱讀量居然過了一萬,而且還有上漲的趨...
    逐夢水鄉(xiāng)閱讀 355評論 16 26