我用的是QT5.12,自帶串口類,類名為
QSerialPort
需要包含的頭文件:
#include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo>
另外在.pro文件中要加入下面這一句,否則編譯的時候會報錯,參見:QT編譯報錯,LNK2019:無法解析的外部符號
QT += serialport
myserial.cpp
#include "myserial.h"
MySerial::MySerial()
{
}
MySerial::~MySerial()
{
if(isOpen()) {
close();
}
}
/**
* \brief 串口初始化
*
* \param[in] port_name:串口名,需與設備管理器上的COM口一致,如"COM1"
* \param[in] baudrate:波特率
* #1200
* #2400
* #4800
* #9600
* #19200
* #38400
* #57600
* #115200
* \param[in] bits:數據位
* #{5, 6, 7, 8}
* \param[in] parity:校驗位
* #'n'/'N':無校驗
* #'e'/'E':偶校驗
* #'o'/'O':奇校驗
* #'0':0校驗,或space parity,校驗位始終為0
* #'1':1校驗,或mark parity,校驗位始終為1
* \param[in] stop:停止位
* #{"1", "1.5", "2"}
* \param[in] flow:流控
* #'n'/'N':不使用流控
* #'h'/'H':硬件流控
* #'s'/'S':軟件流控
*
* \retval 成功返回0,失敗返回-1
*/
int MySerial::MySrtialInit(QString port_name, int baudrate, int bits, char parity, QString stop, char flow)
{
setPortName(port_name);
//檢查串口是否已經打開
if(isOpen()) {
qDebug() << port_name << " is opened";
return -1;
}
//打開串口
if(!open(QIODevice::ReadWrite)) {
qDebug() << port_name << "open failed";
return -1;
}
//設置波特率和讀寫方向,可以傳入第2個參數設置讀寫方向,默認值就是可讀可寫
setBaudRate(QSerialPort::BaudRate(baudrate));
//設置數據位
setDataBits(QSerialPort::DataBits(bits));
//設置校驗位
switch (parity) {
case 'n':
case 'N':
setParity(QSerialPort::NoParity); //無校驗
break;
case 'e':
case 'E':
setParity(QSerialPort::EvenParity); //偶校驗
break;
case 'o':
case 'O':
setParity(QSerialPort::OddParity); //奇校驗
break;
case '0':
setParity(QSerialPort::SpaceParity); //0校驗
break;
case '1':
setParity(QSerialPort::MarkParity); //1校驗
break;
default:
return -1;
}
//設置停止位
if (stop == "1") {
setStopBits(QSerialPort::OneStop); //1位停止位
} else if (stop == "1.5") {
setStopBits(QSerialPort::OneAndHalfStop); //1.5位停止位
} else if (stop == "2") {
setStopBits(QSerialPort::TwoStop); //2位停止位
} else {
return -1;
}
//設置流控
switch (flow) {
case 'n':
case 'N':
setFlowControl(QSerialPort::NoFlowControl); //無流控
break;
case 'h':
case 'H':
setFlowControl(QSerialPort::HardwareControl); //硬件流控
break;
case 's':
case 'S':
setFlowControl(QSerialPort::SoftwareControl); //軟件流控
break;
default:
return -1;
}
//連接信號槽
connect(this, SIGNAL(readyRead()), this, SLOT(receiver()));
return 0;
}
/**
* \brief 數據接收函數
*/
void MySerial::receiver(void)
{
QString dat = readAll();
qDebug() << "read data:" << dat;
}
myserial.h
#ifndef MYSERIAL_H
#define MYSERIAL_H
#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>
//如果不繼承自QSerialPort也要繼承自QObject,因為要使用信號與槽
class MySerial : public QSerialPort
{
Q_OBJECT
private slots:
void receiver(void);
public:
MySerial();
~MySerial();
int MySrtialInit(QString port_name, int baudrate, int bits, char parity, QString stop, char flow); //串口初始化
};
#endif // MYSERIAL_H
main.cpp
#include <QCoreApplication>
#include <QThread>
#include "myserial.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MySerial serial;
if (0 == serial.MySrtialInit("COM3", 115200, 8, 'N', "1", 'N')) {
while (true) {
serial.write("Hello\r\n");
//serial.flush(); //我以為刷新緩沖區后數據就能立馬發送出去,但好像並非如此,原因尚且未知
serial.waitForBytesWritten(); //等待寫入完成
QThread::sleep(1);
}
}
return a.exec();
}
程序運行的效果就是,每隔1S向外發送“Hello\r\n”,收到的數據也會打印出來(不會立馬打印出來,要等sleep結束)
對比總結
一般的平台自帶的串口的校驗位沒有0校驗和1校驗,並且QT自帶的串口可以選擇1.5個停止位,這在一般的平台上是不支持的。但是QT自帶的串口可以選擇的波特率不多,不過常用的幾個波特率都有。
獲取可用的串口
QList<QSerialPortInfo> info = QSerialPortInfo::availablePorts();
for (int i = 0; i < info.length(); i++) {
qDebug() << info[i].portName();
}
