Qt開發串口


首先,在工程文件里面,

QT += serialport

在頭文件里面,

#include <QSerialPort>

1、配置打開串口

QSerialPort* myserial = new QSerialPort():

this->myserial->setPortName("COM1");//待打開的串口號

this->myserial->setBaudRate(9600,QSerialPort::AllDirections);//設置波特率;QSerialPort::AllDirections:雙工

this->myserial->setDataBits(QSerialPort::Data8);//數據位

this->myserial->setParity(QSerialPort::NoParity);//校驗位

this->myserial->setStopBits(QSerialPort::OneStop);//停止位

this->myserial->setFlowControl(QSerialPort::NoFlowControl);//流控制

this->myserial->open(QIODevice::ReadWrite);//打開串口

 2、發送數據

char test[5] = {0x01,0x02,0x03,0x04,0x05};

myserial.write(test);//發送

3、接收數據

定義一個函數作為槽函數,當接收緩沖區有數據的時候回調此函數。

void ReadBuf()

{

  QByteArray dataArray;

  dataArray = myserial->readAll();//讀取數據

  if(!dataArray.isEmpty())

   {

    QString str;

    str = dataArray.toHex();//把數據直接轉化為16進制的字符串形式

    ui->textEdit->setText(str);

   }

}

 此外,在打開串口函數里面關聯信號與槽。已知,當接收緩沖區有數據的時候,串口對象會發送readyRead信號。

QObject::connect(myserial,&QSerialPort::readyRead,this,&MainWindow::ReadBuf);

4、關閉串口

this->myserial->close();

備注一、自動獲取可用串口號,並設置在QComboBox中

1、需要包含頭文件

#include <QSettings>

#include <qt_windows.h>

2、自定義函數

QString getcomm(int index, QString keyorvalue)

{

   HKEY hKey;
    wchar_t keyname[256]; //鍵名數組
    char keyvalue[256];  //鍵值數組
    DWORD keysize,type,valuesize;
    int indexnum;
    QString commresult;
    if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_READ, &hKey) != 0)
    {
        QString error="Cannot open regedit!";
        return error;
    }
    QString keymessage;//鍵名
    QString message;
    QString valuemessage;//鍵值
    indexnum = index;//要讀取鍵值的索引號
    keysize = sizeof(keyname);
    valuesize = sizeof(keyvalue);
    if (RegEnumValue(hKey, indexnum, keyname, &keysize, 0, &type, (BYTE*)keyvalue, &valuesize) == 0)
    {
        for (int i=0; i<(int)keysize; i++)
        {
            message = keyname[i];
            keymessage.append(message);
        }
        for (int j=0; j<(int)valuesize; j++)
        {
            if (keyvalue[j] != 0x00)
                valuemessage.append(keyvalue[j]);
        }
        if (keyorvalue == "key")
            commresult = keymessage;
        if (keyorvalue == "value")
            commresult=valuemessage;
    }
    else
        commresult = "nokey";
    RegCloseKey(hKey);//關閉注冊表
    return commresult;

 

}

3、將可用串口放在QComboBox里面

void MainWindow::InitInterface()
{
    QString path = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM";
    QSettings *settings = new QSettings(path, QSettings::NativeFormat);
    QStringList key = settings->allKeys();
    QStringList comlist;
    comlist.clear();
    /* 取串口名 */
    for (int i=0; i<key.size(); i++)
        comlist << getcomm(i, "value");
    ui->comboBox->addItems(comlist);
}

PS:
1、波特率9600意思是每秒最多傳輸9600/8=1200個字節;
2、如何解決粘包:(以傳輸ascii為例)
1)、接收數據,如果數據長度剛好為協議那么長,則直接解析
2)、如果長度不正確就把此包追加到本地變量中,然后判斷根據報文頭的位置把本地變量去掉報文頭前面的數據(QString::mid)
3)、判斷長度是否足夠(並且本地變量的頭是協議頭),如果足夠則取本地變量前n個數據進行解析,並將本地變量去掉這個包;如果不是協議頭則清空此變量,再次進行循環

PS:開發流程

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM