今天想写一个QT5的串口编程,能够循环发送数据,想具体到us级别,不需要设置ms发送。所以想用一个线程一直发送。
关键问题是碰到在线程循环发送竟然发不出去,见鬼了。。。最后找到问题是要在每次发送后要判断waitForBytesWritten是否发送成功,否则串口再也发不出去了,这很关键。
if(!serial.waitForBytesWritten()) //这一句很关键,决定是否能发送成功
{
qDebug()<<"serial write failed";
}
程序界面:
测试效果:我这里测试用了虚拟串口(vspd)虚拟了两个串口来测试:效果如图:
话不多说,直接贴代码。
首先是mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public:
void setAllState(bool state);
void fillPortsParameters();
QSerialPort serial;
protected:
void run();
void startThread();
void stopThread();
private slots:
void Serial_Read();
void on_SerialClearRecButton_clicked();
void on_SerialSendDataButton_clicked();
void on_SeribalCheckButton_clicked();
void on_SerialOpenButton_clicked();
void on_SendTextEdit_textChanged();
void on_LoopPushButton_clicked();
private:
Ui::MainWindow *ui;
std::atomic m_bRunThread = false;
};
#endif // MAINWINDOW_H
然后是mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//发送按键失能
ui->SerialSendDataButton->setEnabled(false);
ui->LoopPushButton->setEnabled(false);
//connect
connect(&serial, &QSerialPort::readyRead, this, &MainWindow::Serial_Read);
//设置所有下拉框失能;
setAllState(false);
//加入设置参数
fillPortsParameters();
}
MainWindow::~MainWindow()
{
delete ui;
}
// 串口读取数据函数
void MainWindow:: Serial_Read()
{
// QByteArray buf;
// buf = serial.readAll();
// if(!buf.isEmpty())//如果读到的数据不为空
// {
// ui->ReceiveTextEdit->insertPlainText(buf);
// }
// buf.clear();
QByteArray recv;
recv = serial.readAll();
QString recv_string = recv;
qDebug() << recv_string<ReceiveTextEdit->append(recv_string);
}
void MainWindow::on_SerialClearRecButton_clicked()
{
ui->ReceiveTextEdit->clear();
}
void MainWindow::on_SerialSendDataButton_clicked()
{
if(serial.isOpen())
{
//获取界面上的数据并转换成utf8格式的字节流
QByteArray data = ui->SendTextEdit->toPlainText().toUtf8();
qDebug()<SendTextEdit->toPlainText().toUtf8();
serial.write(data);
if(!serial.waitForBytesWritten()) //这一句很关键,决定是否能发送成功
{
qDebug()<<"serial write error";
}
// QThread::msleep(100);
};
qDebug()<<"loopsend thread quit";
}
void MainWindow::on_LoopPushButton_clicked()
{
if(ui->LoopPushButton->text() == "LoopSend")
{
ui->LoopPushButton->setText(tr("STOP"));
startThread();
}
else
{
ui->LoopPushButton->setText(tr("LoopSend"));
stopThread();
}
}
void MainWindow::on_SeribalCheckButton_clicked()
{
ui->SerialNumberComb->clear();
//通过QSerialPortInfo查找可用串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
ui->SerialNumberComb->addItem(info.portName());
}
if(ui->SerialNumberComb->currentIndex() != -1)
{
ui->SerialBaudrateComb->setEnabled(true);
ui->SerialDataBitComb->setEnabled(true);
ui->SerialParityBitComb->setEnabled(true);
ui->SerialStopBitComb->setEnabled(true);
ui->SerialFlowControlComb->setEnabled(true);
}
}
void MainWindow::on_SerialOpenButton_clicked()
{
if(ui->SerialOpenButton->text()==QString("打开串口"))
{
if(!serial.isOpen())
{
//设置串口名
serial.setPortName(ui->SerialNumberComb->currentText());
//设置波特率
serial.setBaudRate(static_cast(ui->SerialBaudrateComb->itemData(ui->SerialBaudrateComb->currentIndex()).toInt()));
//设置数据位数
serial.setDataBits(static_cast(ui->SerialDataBitComb->itemData(ui->SerialDataBitComb->currentIndex()).toInt()));
//设置奇偶校验
serial.setParity(static_cast(ui->SerialParityBitComb->itemData(ui->SerialParityBitComb->currentIndex()).toInt()));
//设置停止位
serial.setStopBits(static_cast(ui->SerialStopBitComb->itemData(ui->SerialStopBitComb->currentIndex()).toInt()));
//设置流控制
serial.setFlowControl(static_cast(ui->SerialFlowControlComb->itemData(ui->SerialFlowControlComb->currentIndex()).toInt()));
//打开串口
if(!serial.open(QIODevice::ReadWrite))
{
QMessageBox::about(NULL,"提示","无法打开串口!");
return;
}
setAllState(false);
ui->SerialNumberComb->setEnabled(false);
ui->SerialOpenButton->setText(QString("关闭串口"));
}
}
else
{
if(serial.isOpen())
{
//关闭串口
serial.close();
//设置串口参数可设置
setAllState(true);
stopThread();
ui->SerialNumberComb->setEnabled(true);
ui->SerialOpenButton->setText(QString("打开串口"));
}
}
}
void MainWindow::setAllState(bool state)
{
if(state)
{
ui->SerialBaudrateComb->setEnabled(true);
ui->SerialDataBitComb->setEnabled(true);
ui->SerialParityBitComb->setEnabled(true);
ui->SerialStopBitComb->setEnabled(true);
ui->SerialFlowControlComb->setEnabled(true);
}
else
{
ui->SerialBaudrateComb->setEnabled(false);
ui->SerialDataBitComb->setEnabled(false);
ui->SerialParityBitComb->setEnabled(false);
ui->SerialStopBitComb->setEnabled(false);
ui->SerialFlowControlComb->setEnabled(false);
}
}
void MainWindow::fillPortsParameters()
{
ui->SerialBaudrateComb->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
ui->SerialBaudrateComb->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
ui->SerialBaudrateComb->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
ui->SerialBaudrateComb->addItem(QStringLiteral("38400"), QSerialPort::Baud57600);
ui->SerialBaudrateComb->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
ui->SerialDataBitComb->addItem(QStringLiteral("5"), QSerialPort::Data5);
ui->SerialDataBitComb->addItem(QStringLiteral("6"), QSerialPort::Data6);
ui->SerialDataBitComb->addItem(QStringLiteral("7"), QSerialPort::Data7);
ui->SerialDataBitComb->addItem(QStringLiteral("8"), QSerialPort::Data8);
ui->SerialDataBitComb->setCurrentIndex(3);
ui->SerialParityBitComb->addItem(tr("None"), QSerialPort::NoParity);
ui->SerialParityBitComb->addItem(tr("Even"), QSerialPort::EvenParity);
ui->SerialParityBitComb->addItem(tr("Odd"), QSerialPort::OddParity);
ui->SerialParityBitComb->addItem(tr("Mark"), QSerialPort::MarkParity);
ui->SerialParityBitComb->addItem(tr("Space"), QSerialPort::SpaceParity);
ui->SerialStopBitComb->addItem(QStringLiteral("1"), QSerialPort::OneStop);
#ifdef Q_OS_WIN
ui->SerialStopBitComb->addItem(tr("1.5"), QSerialPort::OneAndHalfStop);
#endif
ui->SerialStopBitComb->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
ui->SerialFlowControlComb->addItem(tr("None"), QSerialPort::NoFlowControl);
ui->SerialFlowControlComb->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
ui->SerialFlowControlComb->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
}
void MainWindow::on_SendTextEdit_textChanged()
{
if(ui->SendTextEdit->toPlainText().toUtf8() == "")
{
ui->SerialSendDataButton->setEnabled(false);
ui->LoopPushButton->setEnabled(false);
}
else
{
ui->SerialSendDataButton->setEnabled(true);
ui->LoopPushButton->setEnabled(true);
}
}
再然后是 main.cpp
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
程序源码放在这个地址,大家可以去下载。
https://download.csdn.net/download/u010505080/12361152