前言
使用QT的多線程編程,完成串口通信助手的設計。
實施
Qt5下的串口編程
使用QT5.12中自帶的QSerialPort和QSerialPortInf的類實現對串口硬件的訪問,通過對類的方法進行操作,完成整個串口的控制。整個操作基於類的實例,能夠快速部署。這里需要明確層次的概念。串口類,提供了整個串口通信需要的方法,可以直接用於串口的使用。打開串口,即指示該類打開底層串口緩存區,建立連接,實現數據的訪問。讀取數據,在打開串口的條件下,對緩存區的數據進行操作,確保可以得到正確的數據。這三個層次就是串口編程的基本概念。為了降低數據處理對整個界面的影響,將數據通過變量傳遞給多線程下的數據處理模塊。
串口部分的功能設計
//采用指針分配空間的方法實現類的操作
void DialogUart::on_btnUartOpen_clicked() { serial = new QSerialPort; qDebug()<<"uart is open"; }
void DialogUart::on_btnUartClose_clicked() { delete serial; qDebug()<<"uart is close"; } //采用函數的方法實現串口配置及打開 void DialogUart::on_btnConnect_clicked() { //設置串口名 serial->setPortName("COM1"); //設置波特率 serial->setBaudRate(QSerialPort::Baud9600); //設置數據位數 serial->setDataBits(QSerialPort::Data8); //設置奇偶校驗 serial->setParity(QSerialPort::NoParity); //設置停止位 serial->setStopBits(QSerialPort::OneStop); //設置流控制 serial->setFlowControl(QSerialPort::NoFlowControl); serial->open(QIODevice::ReadWrite); } void DialogUart::on_btnDisConnect_clicked() { serial->close(); } //采用按鍵控制接收數據(僅用於測試,實際使用中應使用信號觸發,防止讀取多余的數據) void DialogUart::on_readAll_clicked() { QByteArray buf_read; buf_read = serial->readAll(); QString recv = ui->readText->toPlainText(); recv += QString(buf_read); ui->readText->clear(); ui->readText->append(recv); } //采用按鍵控制寫入 void DialogUart::on_writeAll_clicked() { QByteArray buf_write; buf_write = ui->writeText->text().toUtf8(); serial->write(buf_write); }
整個控制還是比較清晰的。這里基本上滿足了串口調試的常用需求,但是缺少一些控制界面。這些通過控件關聯到參數即可。
在這個簡單的串口控制的基礎上,增加一些多線程控制的功能,用於實現一些數據的自動化處理。
多線程部分的編程
這里多線程采用簡單的繼承QThread的方法,利用run函數的重構進行部分復雜功能的后台運行。根據需求,這里采用正則匹配的方法對串口自動接收的數據進行分割,確保串行數據可以轉化為預期的並行數據。數據通過文件在不同的界面之間進行傳輸,暫時不協調,使用按鈕模擬流程。
QFile fil(QDir::currentPath()+".txt"); fil.open(QIODevice::ReadOnly); char buf[3]; qint64 addr; qint64 length; QString buf_exp; QRegExp exp("[0-9a-fA-F]"); addr=0; while(!m_toStop) { fil.seek(addr); length = fil.read(buf,sizeof (buf)); buf_exp = QString::fromLocal8Bit(buf); if(! exp.indexIn(buf_exp)) { qDebug()<<buf_exp; addr=addr+length; } else { qDebug()<<"error"; addr=addr+1; } if(addr>=fil.size()) { fil.close(); m_toStop = true; } }
重構的run函數可以用於持續讀取和匹配字符函數。本段代碼展示了單位寬度正則匹配字符的簡易操作方法,主要用於記錄和演示。
結果
初步驗證了使用串口類完成數據通信和使用多線程完成通信后的數據匹配處理的操作,為下一步的QT增加處理模型提供了解決方法。