以前一章學習的是第三方庫使用: 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";