QT串口模塊 接收發送數據(一)

本篇介紹一下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();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章