Qt5自带串口通信类,可以直接使用<QSerialPort>
包含的头文件
#include<QtSerialPort/QSerialPort>#include<QtSerialPort/QSerialPortInfo>,来进行串口通信。
下面分享一下自己在开发中的使用方法。
一、获取串口
void MainWindow::listSerialPorts()
{
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->comComboBox->addItem(serial.portName());
serial.close();
}
}
}二、打开串口
void MainWindow::on_openBtn_clicked()
{
if(ui->openBtn->text()=="打开串口")
{
ui->openBtn->setText("关闭串口");
btnSerialEnabledOrDisabled(false);
ui->sendBtn->setEnabled(true);
ui->statusBar->showMessage(ui->comComboBox->currentText()+" 串口打开!");
if(serial==NULL)
serial = new QSerialPort;
serial->setPortName(ui->comComboBox->currentText());
if(!serial->isOpen())
serial->open(QIODevice::ReadWrite);
//设置波特率
switch(ui->baudRateComBox->currentIndex())
{
case 0:
serial->setBaudRate(QSerialPort::Baud9600);break;
case 1:
serial->setBaudRate(QSerialPort::Baud19200);break;
case 2:
serial->setBaudRate(QSerialPort::Baud38400);break;
case 3:
serial->setBaudRate(QSerialPort::Baud57600);break;
case 4:
serial->setBaudRate(QSerialPort::Baud115200);break;
}
//设置数据位
switch(ui->dataBitComBox->currentIndex())
{
case 0:
serial->setDataBits(QSerialPort::Data5);break;
case 1:
serial->setDataBits(QSerialPort::Data6);break;
case 2:
serial->setDataBits(QSerialPort::Data7);break;
case 3:
serial->setDataBits(QSerialPort::Data8);break;
}
//设置校验位
switch (ui->parityComBox->currentIndex())
{
case 0:
serial->setParity(QSerialPort::NoParity);break;
case 1:
serial->setParity(QSerialPort::EvenParity);break;
case 2:
serial->setParity(QSerialPort::OddParity);break;
case 3:
serial->setParity(QSerialPort::MarkParity);break;
case 4:
serial->setParity(QSerialPort::SpaceParity);break;
}
//设置流控
switch (ui->streamCtrlComBox->currentIndex())
{
case 0:
serial->setFlowControl(QSerialPort::NoFlowControl);break;
case 1:
serial->setFlowControl(QSerialPort::HardwareControl);break;// RTS/CTS 硬件流控
case 2:
serial->setFlowControl(QSerialPort::SoftwareControl);break;// XON/XOFF 软件控制数据流传输
}
//设置停止位
switch(ui->stopBitBtn->currentIndex())
{
case 0:
serial->setStopBits(QSerialPort::OneStop);break;
break;
case 1:
serial->setStopBits(QSerialPort::OneAndHalfStop);break;
break;
case 2:
serial->setStopBits(QSerialPort::TwoStop);break;
break;
}
sct->slotsetFlag(true);
}
else
{
ui->openBtn->setText("打开串口");
btnSerialEnabledOrDisabled(true);
ui->spinTimeBox->setEnabled(true);
ui->cmdComboBox->setEnabled(true);
ui->sendBtn->setEnabled(false);
ui->statusBar->showMessage(ui->comComboBox->currentText()+" 串口关闭!");
sct->slotsetFlag(false);
}
}三、读取串口数据
建议通信方法:通过信号槽的方式实现读取串口数据。
connect(serial,SIGNAL(readyRead()),this,SLOT(getSpData()));
connect(timer,SIGNAL(timeout()),this,SLOT(dealTimeOut()));第一步:打开串口后,连接信号槽;
第二步:建一个定时器,每隔一段时间比如(20ms),在槽函数里面启动定时器,
void mainWindow::getSpData()
{
timer->start(20);
//QByteArray tmp;放在.h文件里 tmp即接收到的数据
tmp.push_back(serial->readAll());
}第三步:处理超时函数,超时函数里面需要对串口接收到的数据进行处理。
void mainWindow::dealTimeOut()
{
timer->stop();
//此时再定义一个QString spData,并将tmp的数据赋值给spData。
//在此处对接收的数据spData进行处理
//....
}四、串口写入数据
QByteArray b;
...
...
serial->write(b);如果写入失败,需要在write之后加入serial->waitForBytesWritten()。
在子线程中,在write之后,必须要等待写出去完毕才执行下一步,否则线程跑到别的地方进行休眠就会把数据缓存到iodevice中:
五、串口关闭
serial->close();六、建议
串口的发送数据和接收数据不要放在一个函数里面,如有必要可以发送和接收各一个线程。发送的数据和接收的数据分别处理,互不影响。
如遇字节转换参考该文章:https://blog.csdn.net/weixin_41882459/article/details/106232163
版权声明:本文为weixin_41882459原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。