前言
每次写串口相关的功能时,总是需要重新写或者复制原来写过的文件,容易出错不说,这也不是码农的风格,所以还是得有一套自己得代码库,方便调用,又能保持神秘感。
一、开发需求
1.有个实例类;
2.设置串口参数:COM,Baudrate,databits等;
3.打开,关闭;
4.发送,接收功能,而且数据类型比较多;
5.bytearry和hex转换;
6.定时发送(非必要);
7.获取所有串口;
8.串口当前状态;
二、工作流
三、实现过程
1.创建lib,名称为 Serialportlibrary
2.pro中添加 QT += serialport .h中添加引用
3.定义参数(.h)
QSerialPort *m_serialPort;
QTimer *m_timer;
QByteArray m_timerSendData;
4.修改类(.cpp),AutoRead是手动添加的,用来区分是否自动读取数据,还是可自定义读取数据。
Serialportlibrary::Serialportlibrary(bool AutoRead, QObject *parent):QObject(parent)
{
m_serialPort = new QSerialPort(this);//实例化串口
m_timer = new QTimer(this);//实例化timer
if(AutoRead)
connect(m_serialPort, &QSerialPort::readyRead, this, &Serialportlibrary::handleReadyRead);
connect(m_timer, &QTimer::timeout, this, &Serialportlibrary::handleTimeout);
}
5.析构,主要是关闭串口,否则连续操作会有问题。
Serialportlibrary::~Serialportlibrary()
{
if (m_serialPort->isOpen()) {
m_serialPort->close();
}
}
6.获取所有串口,并返回一个QString的List格式,可以直接用Combobox调用。
QList<QString> Serialportlibrary::getSerialPorts()
{
QList<QString> stringlist;
QList<QSerialPortInfo> portInfoList;
portInfoList = QSerialPortInfo::availablePorts();
for(const QSerialPortInfo &portinfo:portInfoList)
{
stringlist.append(portinfo.portName());
}
return stringlist;
}
7.设置Serial参数,只有设置,没有打开操作,返回状态(内部可以判断,但是我直接判断是否能打开串口,这里默认true)。
bool Serialportlibrary::setSerialPortParams(const QString &portName, qint32 baudRate,
QSerialPort::DataBits dataBits,
QSerialPort::Parity parity,
QSerialPort::StopBits stopBits,
QSerialPort::FlowControl flowControl)
{
m_serialPort->setPortName(portName);
m_serialPort->setBaudRate(baudRate);
m_serialPort->setDataBits(dataBits);
m_serialPort->setParity(parity);
m_serialPort->setStopBits(stopBits);
m_serialPort->setFlowControl(flowControl);
return true;
}
8.打开串口,返回bool值
bool Serialportlibrary::openSerialPort()
{
if (m_serialPort->open(QIODevice::ReadWrite)) {
return true;
}
return false;
}
9.关闭串口,要判断是否open,ClearBuffer在后面(可以和open放在一起,但是尽量结构简单化,愿意的话可以自己二次封装)。
void Serialportlibrary::closeSerialPort()
{
if (m_serialPort->isOpen()) {
ClearBuffer();
m_serialPort->close();
}
}
10.发送,共2种方式。
qint64 Serialportlibrary::sendData(const QByteArray &data)
{
if (m_serialPort->isOpen()) {
return m_serialPort->write(data);
}
return -1;
}
qint8 Serialportlibrary::sendData(char data)
{
if(m_serialPort->isOpen())
{
return m_serialPort->write(&data,1);
}
return -1;
}
11.转换,注意这个转换是自定义的,2个char中间添加空格,备用的方法,在库里没用到,在外面可以调用。
QByteArray Serialportlibrary::hexStringToByteArray(const QString &hexString)
{
QByteArray byteArray;
QString trimmedHex = hexString.trimmed();
for (int i = 0; i < trimmedHex.length(); i += 2) {
QString byteString = trimmedHex.mid(i, 2);
bool ok;
char byte = static_cast<char>(byteString.toInt(&ok, 16));
if (ok) {
byteArray.append(byte);
}
}
return byteArray;
}
QString Serialportlibrary::byteArrayToHexString(const QByteArray &byteArray)
{
return byteArray.toHex(' ').toUpper();
}
12.接收,如果定义AutoRead,则自动发射信号,否则需要手动读取,接收返回值
//自动读取
void Serialportlibrary::handleReadyRead()
{
QByteArray data = m_serialPort->readAll();
emit dataReceived(data);
}
//手动读取
QByteArray Serialportlibrary::ReadData(uint8_t size)
{
if(size != 0)
return m_serialPort->read(size);
else
return m_serialPort->readAll();
}
13.定时发送
//设置发送事件间隔
void Serialportlibrary::setTimerInterval(int interval)
{
m_timer->setInterval(interval);
}
//开始发送
void Serialportlibrary::startTimerSend(const QByteArray &data)
{
m_timerSendData = data;
m_timer->start();
}
//停止发送
void Serialportlibrary::stopTimerSend()
{
m_timer->stop();
}
//触发发送
void Serialportlibrary::handleTimeout()
{
sendData(m_timerSendData);
}
14.清除buffer,在关闭Serial时调用,防止再打开后还有上次的数据。
void Serialportlibrary::ClearBuffer()
{
if(m_serialPort->isOpen())
m_serialPort->clear();
}
15.串口是否打开检测
bool Serialportlibrary::ComIsOpen()
{
if(m_serialPort->isOpen())
return true;
return false;
}
四、结尾
这就完成了串口的基本功能与需求,上层需要自己去进行二次开发,库只保留最基本最通用的功能。
本人想创建一些基础的开源库使用,大家可以使用,也可以帮忙完善。