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

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

本章來學習自帶serial庫函數

 

1.QSerialPortInfo學習

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

示例以下:this

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初始化編碼

初始化以下所示:spa

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示例code

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());    //發送隨機值
}

運行打印:htm

 

發現下位機發送上來的是亂碼的,這是由於咱們下位機程序是用的gbk編碼寫的,因此打印漢字亂碼了blog

 

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";
相關文章
相關標籤/搜索