前言
? ? ? ? 每次寫串口相關的功能時,總是需要重新寫或者復制原來寫過的文件,容易出錯不說,這也不是碼農的風格,所以還是得有一套自己得代碼庫,方便調用,又能保持神秘感。
一、開發需求
? ? ? ? 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);//實例化timerif(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);elsereturn 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;
}
四、結尾
? ? ? ? 這就完成了串口的基本功能與需求,上層需要自己去進行二次開發,庫只保留最基本最通用的功能。
? ? ? ? 本人想創建一些基礎的開源庫使用,大家可以使用,也可以幫忙完善。
generaltoolshttps://gitee.com/klein_tools/general_tools? ? ? ??