本篇介绍一下QT串口使用,接收发送数据。
QT的实用性、便捷性和广泛性就不多说了,直接进入主题,在使用的时候,需要包含串口类(QT5,QT4需要额外下载串口类)。
QT += core gui serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SeatControl
TEMPLATE = app
接着需要包含一些头文件,串口的使用以及串口设备信息等。
#include
#include
之后定义串口类,并在构造函数中初始化。
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();