我用的是QT5.12,自带串口类,类名为

QSerialPort

  需要包含的头文件:

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

  另外在.pro文件中要加入下面这一句,否则编译的时候会报错,参见:QT编译报错,LNK2019:无法解析的外部符号

1
QT += serialport

myserial.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#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

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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自带的串口可以选择的波特率不多,不过常用的几个波特率都有。

获取可用的串口

  

1
2
3
4
QList<QSerialPortInfo> info = QSerialPortInfo::availablePorts();
for (int i = 0; i < info.length(); i++) {
    qDebug() << info[i].portName();
}