我用的是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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #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
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(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?