本篇介紹一下QT串口使用,接收發送數據。
QT的實用性、便捷性和廣泛性就不多說了,直接進入主題,在使用的時候,需要包含串口類(QT5,QT4需要額外下載串口類)。
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SeatControl
TEMPLATE = app
接着需要包含一些頭文件,串口的使用以及串口設備信息等。
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
之後定義串口類,並在構造函數中初始化。
QSerialPort *MySerialPort = nullptr; //串口類
SCParameter::SCParameter(QWidget *parent) :
QWidget(parent),
ui(new Ui::SCParameter),
MySerialPort(new QSerialPort),
然後尋找端口信息,調用availablePorts()函數就可以找到可用的端口。comboBoxComPort 控件保存端口信息。
void SCParameter::Refresh()
{
QList <QSerialPortInfo> InfoList = QSerialPortInfo::availablePorts(); //獲取可用端口,並加入鏈表
ui->comboBoxComPort->clear(); //清空Combox顯示內容
if(InfoList.isEmpty())
ShowMessage(tr("未找到可用的端口"),1500);
else
{
foreach(QSerialPortInfo Info,InfoList)
ui->comboBoxComPort->addItem(Info.portName() + ' ' + Info.description()); //ComBox加入可用端口號
}
}
再然後就是打開端口,配置端口信息,比如波特率,數據位,奇偶校驗,停止位等這些信息。
MySerialPort->setPortName(PortName); //設置要打開的端口名
MySerialPort->open(QIODevice::ReadWrite); //打開端口
MySerialPort->setBaudRate(115200); //設置端口參數
MySerialPort->setDataBits(QSerialPort::Data8);
MySerialPort->setParity(QSerialPort::NoParity);
MySerialPort->setStopBits(QSerialPort::OneStop);
MySerialPort->setFlowControl(QSerialPort::NoFlowControl);
做完這些工作就可以向指定的端口發送數據,
void SCParameter::WriteBytes(QByteArray Data)
{
if(MySerialPort->isOpen())
{
MySerialPort->write(Data);
}
else
{
ShowMessage(ui->comboBoxComPort->currentText().split(' ').first()+tr("端口未打開,不能發送數據!"),2000);
}
}
對於接收數據,QSerialPort類有成員函數(readyRead())來接收數據,所以先綁定槽函數,然後延時一段時間,延時到則接收數據完成。
connect(MySerialPort,SIGNAL(readyRead()),this,SLOT(ReadRecData()));
while (mpSerialPort->waitForReadyRead(readDelayTime()));
QByteArray RecData=MySerialPort->readAll(); //讀取接收數據
但是存在一個問題,短時這樣接收數據還可以,時間一長,就會因爲while循環的原因死機,因爲是阻塞的機制。
所以後來參考網上的做法,用定時器定時接收數據,定時一段時間,一段時間之後,自動認爲接收數據完成,這樣轉換成了非阻塞機制,不影響其他控件的使用以及全局的響應。
void SCParameter::ReadRecData()
{
MyTimer->start(20);
FrameRecData.append(MySerialPort->readAll());
}
void SCParameter::FrameRecDataProcess()
{
MyTimer->stop();
FrameRecData............//處理數據
}
最後就是關閉串口之後,纔可以打開另外的端口,發送和接收數據等操作。
MySerialPort->close();