基于Qt的串口包装器
头文件
#ifndef SERIALPORTWRAP_H
#define SERIALPORTWRAP_H
#pragma execution_character_set("utf-8")
#include <QObject>
#include <QSerialPort>
class SerialPortWrap : public QObject
{
Q_OBJECT
public:
static QMap<QString,QSerialPort::Parity> getParityMap();
static QMap<QString,QSerialPort::DataBits> getDataMap();
static QMap<QString,QSerialPort::StopBits> getStopMap();
static QMap<QString, QSerialPort::FlowControl> getFlowMap();
public:
explicit SerialPortWrap(QObject *parent = nullptr);
void setSerialPort(QSerialPort *port);
bool sendNoReply(QByteArray data);
bool sendReply(QByteArray data, QByteArray &rec);
signals:
void receivedData(QByteArray data);
public slots:
private:
QSerialPort *_serial=nullptr;
QList<QByteArray> _recList;
void waitMs(int ms);
private slots:
void onError(QSerialPort::SerialPortError err);
void onReadyReady();
};
#endif // SERIALPORTWRAP_H
cpp
#include <QMap>
#include <QDebug>
#include <QEventLoop>
#include <QElapsedTimer>
#include <QTimer>
#include "serialportwrap.h"
QMap<QString, QSerialPort::Parity> SerialPortWrap::getParityMap()
{
QMap<QString,QSerialPort::Parity> parityMap={
{"NoPraity",QSerialPort::NoParity},
{"EvenParity",QSerialPort::EvenParity},
{"OddParity",QSerialPort::OddParity},
{"SpaceParity",QSerialPort::SpaceParity},
{"MarkParity",QSerialPort::MarkParity}
};
return parityMap;
}
QMap<QString, QSerialPort::DataBits> SerialPortWrap::getDataMap()
{
QMap<QString,QSerialPort::DataBits> dataMap={
{"Data5",QSerialPort::Data5},
{"Data6",QSerialPort::Data6},
{"Data7",QSerialPort::Data7},
{"Data8",QSerialPort::Data8}
};
return dataMap;
}
QMap<QString, QSerialPort::StopBits> SerialPortWrap::getStopMap()
{
QMap<QString,QSerialPort::StopBits> stopMap={
{"OneStop",QSerialPort::OneStop},
{"OneAndHalfStop",QSerialPort::OneAndHalfStop},
{"TwoStop",QSerialPort::TwoStop}
};
return stopMap;
}
QMap<QString, QSerialPort::FlowControl> SerialPortWrap::getFlowMap()
{
QMap<QString,QSerialPort::FlowControl> flowMap={
{"NoFlowControl",QSerialPort::NoFlowControl},
{"HardwareControl",QSerialPort::HardwareControl},
{"SoftwareControl",QSerialPort::SoftwareControl},
{"UnknownFlowControl",QSerialPort::UnknownFlowControl}
};
return flowMap;
}
SerialPortWrap::SerialPortWrap(QObject *parent) : QObject(parent)
{
}
void SerialPortWrap::setSerialPort(QSerialPort *port)
{
_serial=port;
connect(_serial,&QSerialPort::errorOccurred,this,&SerialPortWrap::onError);
connect(_serial,&QSerialPort::readyRead,this,&SerialPortWrap::onReadyReady);
}
bool SerialPortWrap::sendNoReply(QByteArray data)
{
_recList.clear();
return _serial->write(data)!=-1;
}
bool SerialPortWrap::sendReply(QByteArray data,QByteArray &rec)
{
_recList.clear();
_serial->write(data);
QElapsedTimer ela;
ela.start();
while(_recList.count()==0)
{
waitMs(100);
if(ela.elapsed()>3000)
{
throw QString("%1 time out").arg(_serial->portName());
}
}
waitMs(50);
QByteArray arr;
for(int i=0;i<_recList.count();i++)
{
arr.append(_recList.at(i));
}
rec=arr;
return true;
}
void SerialPortWrap::waitMs(int ms)
{
QEventLoop loop;
QTimer::singleShot(ms, &loop, &QEventLoop::quit); // 设置定时器,在超时时退出事件循环
loop.exec(); // 进入事件循环
}
void SerialPortWrap::onError(QSerialPort::SerialPortError err)
{
qDebug()<<__FUNCTION__<<__LINE__<<_serial->portName()<<_serial->errorString();
}
void SerialPortWrap::onReadyReady()
{
QByteArray arr=_serial->readAll();
_recList.append(arr);
emit receivedData(arr);
}
效果图: