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();
发布了23 篇原创文章 · 获赞 41 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34430371/article/details/105137927
今日推荐