Qt 项目:多串口测试工具(MacOS以及Windows平台)
项目地址:多线程多串口测试工具https://gitee.com/lsqiscool/sata_test.git
项目介绍:由于串口较多,采用多线程,某几个串口公用一个线程;对连接的多个串口进行识别;对需要的测试的串口进行勾选;设定测试数据;对测试串口返回数据进行特判;设定串口波特率;在设定的时间内,对某一串口进行反复测试;设定串口发送时间间隔;对测试日志进行输出。
窗体运行界面:(没加margin限定。有点乱。。)
文件架构:
串口类
主要功能都在串口类,sataCon,为了进行多线程操作,继承自QObject,其中三个timer分别为总体测试时间、接收数据、间隔发送,serial为Qt封装的串口类对象。
该类基本逻辑为:
- 对于某个串口的测试时,主线程向子线程发送信号,触发槽函数sataConTest(),启动开始测试timer(timerIntreval、totalTimer),每个timerIntraval结束时,发送一次测试内容;
- 当串口收到readyRead信号时,触发timer(timerReceiver),该timer结束后,开始读取串口数据(防止数据读取不完整),读取数据加入List(receiveDataSet),每当receiveDataSet到1000条则写入byteToFile,主线程中定时将byteToFile写入文件,并清空;
- totalTimer结束后,线程发出信号至主线程。
串口我进行了短接,即发什么收什么。
类定义:
class sataCon: public QObject
{
Q_OBJECT
public:
QTimer* myTimerTotal;
QTimer* myTimerReceive;
QTimer* myTimerInterval;
QSerialPort* serial;
QList<QList<QByteArray>> byteToFile;
explicit sataCon(QObject *parent = NULL);
~sataCon();
sataCon(QByteArray _byteArray, QString _serial, QString _baud);
signals:
void sataTestTimeout();
public slots:
// void reveiveData();
void handleData();
void sataConTest();
void sataSetInfor(QByteArray _byteArray, QString _serial,
QString _baud, int _totalTime, int _intervalTime);
void stopTestFromOutSide();
private:
QList<QByteArray> receiveDataSet;
QByteArray byteArray;
QByteArray receiveByteArray;
QString baud;
int totalTime;
int intervalTime;
void initPort();
void sendData();
void stopTest();
};
类内实现:
构造函数:
初始化timer和serial
sataCon::sataCon(QObject *parent) : QObject(parent)
{
/*...*/
myTimerReceive = new QTimer;
myTimerReceive->setTimerType(Qt::PreciseTimer);
myTimerInterval = new QTimer;
myTimerInterval->setTimerType(Qt::PreciseTimer);
myTimerTotal = new QTimer;
myTimerTotal->setTimerType(Qt::PreciseTimer);
serial = new QSerialPort();
}
set函数:
set配置信息,包括发送数据、串口名称、波特率、总测试时间、发送间隔
void sataCon::sataSetInfor(QByteArray _byteArray, QString _serial,
QString _baud, int _totalTime, int _intervalTime)
{
byteArray = _byteArray;
// serial = new QSerialPort();
serial->setPortName(_serial);
baud = _baud;
totalTime = _totalTime * 60 * 1000;
intervalTime = _intervalTime;
receiveByteArray.clear();
byteToFile = {};
initPort();
}
init函数:
对串口、Timer进行初始化,绑定Timer的槽函数
void sataCon::initPort()
{
if (serial->open(QIODevice::ReadWrite))
{
qDebug() << serial->portName() << "Port have been opened";
}
else
{
qDebug() << serial->portName() << "open failed";
}
if (baud == QString("9600"))
{
serial->setBaudRate(QSerialPort::Baud9600);
}
else if (baud == QString("19200"))
{
serial->setBaudRate(QSerialPort::Baud19200);
}
else if (baud == QString("38400"))
{
serial->setBaudRate(QSerialPort::Baud38400);
}
else if (baud == QString("57600"))
{
serial->setBaudRate(QSerialPort::Baud57600);
}
else if (baud == QString("115200"))
{
serial->setBaudRate(QSerialPort::Baud115200);
}
else if (baud == QString("460800"))
{
serial->setBaudRate(QSerialPort::Baud460800);
}
connect(serial, &QSerialPort::readyRead, this, [=](){
myTimerReceive->start(10);
}, Qt::QueuedConnection);
connect(myTimerReceive, &QTimer::timeout, this, &sataCon::handleData, Qt::QueuedConnection);
connect(myTimerInterval, &QTimer::timeout, this, &sataCon::sendData, Qt::QueuedConnection);
connect(myTimerTotal, &QTimer::timeout, this, &sataCon::stopTest, Qt::DirectConnection);
}
处理收到信息,以及相应开始结束槽函数和发送数据的函数
void sataCon::handleData()
{
myTimerReceive->stop();
receiveByteArray.append(serial->readAll());
receiveDataSet << receiveByteArray;
// qDebug() << receiveDataSet.size() << "----------";
receiveByteArray = "";
if (1000 == receiveDataSet.size())
{
byteToFile.append(receiveDataSet);
receiveDataSet.clear();
}
}
void sataCon::sataConTest()
{
if (serial->isOpen())
{
qDebug() << serial->portName() << "Start Test!";
myTimerTotal->start(totalTime);
myTimerInterval->start(intervalTime);
}
else
{
qDebug() << serial->portName() << "open failed";
}
}
void sataCon::sendData()
{
// qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") << " start";
serial->write(byteArray + "\r\n");
// qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") << " end";
}
void sataCon::stopTest()
{
myTimerInterval->stop();
myTimerTotal->stop();
serial->clear();
serial->close();
emit sataTestTimeout();
qDebug() << "Stop cause timeout";
}
void sataCon::stopTestFromOutSide()
{
myTimerInterval->stop();
myTimerTotal->stop();
serial->clear();
serial->close();
qDebug() << "Stop cause button click";
}
ui界面
没啥说的,由于要对16个串口进行同时测试,控件有点多。