46.QT-自帶庫QSerialPort串口使用


之前一章學習的是第三方庫使用: 34.QT-qextserialport第三方庫制作串口助手(並動態檢測在線串口,附帶源碼)

本章來學習自帶serial庫

 

1.QSerialPortInfo

QList<QSerialPortInfo>  QSerialPortInfo::availablePorts();      
         //獲取當前在線的串口設備

示例如下:

foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{

        qDebug() << "Name : " << info.portName();

        qDebug() << "Description : " << info.description();

        qDebug() << "Manufacturer: " << info.manufacturer();

        qDebug() << "Serial Number: " << info.serialNumber();

        qDebug() << "System Location: " << info.systemLocation();
}

 

2.QSerialPort初始化

初始化如下所示:

serialport.setPortName(cfg.portName);
serialport.setBaudRate(QSerialPort::Baud115200);
serialport.setParity(QSerialPort::NoParity);
serialport.setDataBits(QSerialPort::Data8);
serialport.setStopBits(QSerialPort::OneStop);
serialport.setFlowControl(QSerialPort::NoFlowControl);
if(!serialport.open(QIODevice::ReadWrite))
{
      qDebug()<<"打開失敗";
      return;
}

 

3.QSerialPort信號介紹

void readyRead();           
//當串口接收到下位機發送數據時,將會發送該信號,然后我們在對應的槽函數調用serialport .readAll()即可

error(QSerialPort::SerialPortError );
//串口錯誤信號,比如當串口打開失敗,串口連接時突然斷開,都將會調用該信號
//比如:  QSerialPort::PermissionError (表示串口連接斷開了)

 

4.QSerialPort示例

Widget::Widget(QWidget *parent)
    : QWidget(parent),
      serialport(this),
      btn("發送",this)
{
    serialport.setPortName("COM21");
    serialport.setBaudRate(QSerialPort::Baud115200);
    serialport.setParity(QSerialPort::NoParity);
    serialport.setDataBits(QSerialPort::Data8);
    serialport.setStopBits(QSerialPort::OneStop);
    serialport.setFlowControl(QSerialPort::NoFlowControl);
    if(!serialport.open(QIODevice::ReadWrite))
    {
          qDebug()<<"打開失敗";
          return;
    }
    connect(&serialport,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    connect(&btn,SIGNAL(clicked()),this,SLOT(sendSerialData()));  
}

void Widget::onReadyRead()
{
    QString str(serialport.readAll());
    qDebug()<<str;
}
void Widget::sendSerialData()
{
     serialport.write(QString("發送:%1\r\n").arg(qrand()).toLocal8Bit());    //發送隨機值
}

運行打印:

 

發現下位機發送上來的是亂碼的,這是因為我們下位機程序是用的gbk編碼寫的,所以打印漢字亂碼了

 

5.修改代碼-添加數據格式編碼轉換

修改發送/接收函數:

void Widget::onReadyRead()
{
     QString str(fromGBKtoUtf8(serialport.readAll()));
     QStringList  list = str.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);      //去掉\r\n , SkipEmptyParts表示如果末尾為\r\n則不需要打印

     foreach (QString line, list) {
       qDebug()<<line;
    }
}

void Widget::sendSerialData()
{
    //serialport.write(QString("%1\r\n").arg(qrand()).toLocal8Bit());
     serialport.write(fromUtf8toGBK(QString("%1\r\n").arg(qrand())));
}

QString  Widget::fromGBKtoUtf8(QByteArray arry)
{
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

    QString unicode=gbk->toUnicode(arry);
    return QString(utf8->fromUnicode(unicode));
}

QByteArray Widget::fromUtf8toGBK(QString str)
{
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    QString unicode=utf8->toUnicode(str.toLocal8Bit());
    return gbk->fromUnicode(unicode);
}

運行打印:

 

 

6.在QThread線程中使用QSerialPort

由於在QThread線程里不能用槽函數,不過可以在run里使用QSerialPort::waitForReadyRead()來阻塞獲取讀數據.如果在指定時間內讀取成功/失敗,則向界面發送數據.

示例如下:

       serialport.write( QString("%1\r\n").arg(qrand()).toLocal8Bit() );    //寫入隨機值
       if(serialport.waitForBytesWritten(100))  //100ms 等待寫入成功
       {
            if(serialport.waitForReadyRead(100))  //等待數據返回
            {
                QString str((serialport.readAll()));
                QStringList  list = str.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);      //去掉\r\n

                foreach (QString line, list) {

                  qDebug()<<line;

                  //解析line,並向界面發送信號 ... ...
               }
            }
            else
               qDebug()<<"read err";
       }
       else
          qDebug()<<"write err";

 

 


免責聲明!

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



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