我用的是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(); }