读写串口 类QSerialPort
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读写串口 类QSerialPort相关的知识,希望对你有一定的参考价值。
参考技术A 背景:一个串口下位机(黑盒子)我每次发送数据,黑盒子都会发送回来状态,测试情况1
1、自定义一个类myQSerialPort 继承QSerialPort,槽函数接收回复的状态(发送的信号量为AA,BB) (QSerialPort 改为成员变量依旧有这个问题)
定义了变量 m__myQSerialPort,有一个写方法 B(B方法组织数据并发送数据)
m_mutex.lock();//m_mute为QMutex
发送
m_mutex.unlock();
我是在线程 发送完数据,等到接收到 回复的状态在继续执行
2、一个 线程类 myQThread 发送信号量 A , 然后主线程 发送数据,接收到信号 AA 线程继续运行,
3、主线程中有一个定时器调用 m__myQSerialPort.B(),
等到BB信号量 ,
测试结果发现有时 发送信号量完 A会出现线程不继续执行了, 最后使用串口监控软件,m__myQSerialPort.B()发送的数据和信号量完A发送的 数据被一下 发送给黑盒子了,其不能正常解析,所以就收不到 AA信号量, 线程就 不能执行了,
串口例子
myserial::myserial()
m_pCurrThread = new QThread;
m_pSerial = new QSerialPort;
this->moveToThread(m_pCurrThread);
m_pSerial->moveToThread(m_pCurrThread);
connect(m_pCurrThread, &QThread::started, this, &myserial::OpenSerial);
connect(this, &myserial::SignalWriteData, this, &myserial::WriteData);
m_pCurrThread->start();
void myserial::readyRead()
qDebug()<<"readyRead = "<<QThread::currentThreadId()<<"\n";
qDebug() << m_pSerial->readAll().length();
void myserial::OpenSerial()
qDebug()<<"OpenSerial = "<<QThread::currentThreadId()<<"\n";
m_pSerial->setPortName(QString("COM4"));
m_pSerial->setBaudRate( 115200 );
m_pSerial->setDataBits(QSerialPort::Data8);
m_pSerial->setParity(QSerialPort::NoParity);
m_pSerial->setStopBits(QSerialPort::OneStop);
m_pSerial->open(QIODevice::ReadWrite);
connect(m_pSerial, &QSerialPort::readyRead, this, &myserial::readyRead,Qt::QueuedConnection);
void myserial::run()
unsigned char data[6] = 0X5E,1,1,0,6,0x66 ;
qDebug()<<"run = "<<QThread::currentThreadId()<<"\n";
for( int i =0;i< 30;i++)
emit SignalWriteData();
QThread::sleep(1);
void myserial::WriteData()
qDebug()<<"WriteData = "<
unsigned char data[6] = 0X5E,1,1,0,6,0x66 ;
if( m_pSerial->write( (char*)data, 6) < 0 )
qDebug() <<"write fail";
//以上办法 是在在 槽函数中打开 串口,在构造函数中mobetothread
//以下改为在 公有的成员函数中 打开串口 然后moveToThread
#include "myserial.h"
#include
myserial::myserial()
m_pCurrThread = new QThread;
m_pSerial = new QSerialPort;
this->moveToThread(m_pCurrThread);
//connect(m_pCurrThread, &QThread::started, this, &myserial::OpenSerial);
connect(this, &myserial::SignalWriteData, this, &myserial::WriteData);
m_pCurrThread->start();
void myserial::readyRead()
qDebug()<<"readyRead = "<<QThread::currentThreadId()<<"\n";
qDebug() << m_pSerial->readAll().length();
bool myserial::OpenSerial()
qDebug()<<"OpenSerial = "<<QThread::currentThreadId()<<"\n";
m_pSerial->setPortName(QString("COM5"));
m_pSerial->setBaudRate( 115200 );
m_pSerial->setDataBits(QSerialPort::Data8);
m_pSerial->setParity(QSerialPort::NoParity);
m_pSerial->setStopBits(QSerialPort::OneStop);
bool tf = m_pSerial->open(QIODevice::ReadWrite);
//m_pSerial->moveToThread(m_pCurrThread);//都可以
QMetaObject::Connection aa = connect(m_pSerial, &QSerialPort::readyRead, this, &myserial::readyRead,Qt::QueuedConnection);
m_pSerial->moveToThread(m_pCurrThread);
return tf;
void myserial::run()
unsigned char data[6] = 0X5E,1,1,0,6,0x66 ;
qDebug()<<"run = "<<QThread::currentThreadId()<<"\n";
for( int i =0;i< 30;i++)
emit SignalWriteData();
QThread::sleep(1);
void myserial::WriteData()
qDebug()<<"WriteData = "<<QThread::currentThreadId()<<"\n";
unsigned char data[6] = 0X5E,1,1,0,6,0x66 ;
if( m_pSerial->write( (char*)data, 6) < 0 )
qDebug() <<"write fail";
Qt5 串口类QSerialPort
简述:
在Qt5以上提供了QtSerialPort模块,方便编程人员快速的开发应用串口的应用程序。
QtSerialPort模块中提供了两个C++类,分别是QSerialPort 和QSerialPortInfo。
QSerialPort 类是Qt5封装的串口类,可与串口进行通信,提供了操作串口的各种接口。
QSerialPortInfo类是一个辅助类,可以提供计算机中可用串口的各种信息。如可用的串口名称,描述,制造商,序列号,串口16位产品编号等。利用QSerialPortInfo提供的可用串口信息,可设置串口波特率,并打开需要的串口进行通信。
使用Qt5进行串口通信大致步骤为:配置串口参数->打开串口->收发数据。
要使用QtSerialPort模块,需要在工程文件.pro文件或.pri中增加语句:
QT += serialport
Qt版本:5.12.8
1.QSerialPortInfo类
列举出电脑上全部的串口设备,Cpp 文件如下:
#include <QCoreApplication>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
qDebug() << "Name : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
qDebug() << "Serial Number: " << info.serialNumber();
qDebug() << "System Location: " << info.systemLocation();
return a.exec();
显示的结果如下:
Name : "COM17"
Description : "USB-SERIAL CH340"
Manufacturer: "wch.cn"
Serial Number: ""
System Location: "\\\\\\\\.\\\\COM17"
Name : "COM1"
Description : "通信端口"
Manufacturer: "(标准端口类型)"
Serial Number: ""
System Location: "\\\\\\\\.\\\\COM1"
Name : "COM16"
Description : "Prolific USB-to-Serial Comm Port"
Manufacturer: "Prolific"
Serial Number: "A400G3UXA"
System Location: "\\\\\\\\.\\\\COM16"
Name : "COM11"
Description : "Prolific USB-to-Serial Comm Port"
Manufacturer: "Prolific"
Serial Number: ""
System Location: "\\\\\\\\.\\\\COM11"
若USB串口每次插在不同的USB口上时获得的串口名称可能有变化,这时可以利用串口的序列号,指定程序使用某一个确定的串口。
#include <QCoreApplication>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>
int main(int argc, char *argv[])
QCoreApplication a(argc, argv);
QSerialPortInfo com_info;
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
if( info.serialNumber() == "A400G3UXA" )
com_info = info;
break;
qDebug() << "Name : " << com_info.portName();
qDebug() << "Description : " << com_info.description();
qDebug() << "serialNumber: " << com_info.serialNumber();
return a.exec();
2.QSerialPort类
QSerialPort 类提供了操作串口的各种接口。
头文件:
class MySerial : public QObject
Q_OBJECT
public:
MySerial(QString portName = "ttyUSB1", QObject *parent = nullptr);
~MySerial();
bool WriteToSerial(QByteArray cmd);
QByteArray ReadFromSerial();
bool SerialIsOpen() return m_SerialPort->isOpen();
void closeSerial();
signals:
void sig_SendTipInfo(bool result, QString info);
void sig_SendReadData(QByteArray data);
private:
QSerialPort *m_SerialPort = nullptr;
;
cpp文件:
MySerial::MySerial(QString portName, QObject *parent) :
QObject(parent)
m_SerialPort = new QSerialPort();
m_SerialPort->setPortName(portName); //设置串行端口的名称
m_SerialPort->setBaudRate(QSerialPort::Baud115200); //波特率:115200 bps
m_SerialPort->setDataBits(QSerialPort::Data8); //数据位:8 位
m_SerialPort->setStopBits(QSerialPort::OneStop); //停止位:1 位
m_SerialPort->setParity(QSerialPort::NoParity); //校验位:无
m_SerialPort->setFlowControl(QSerialPort::NoFlowControl);
qDebug() << "Port Name:" << portName;
if(!m_SerialPort->open(QIODevice::ReadWrite))
emit sig_SendTipInfo(false, "opened failed");
qDebug() << "open failed";
else qDebug() << "open successfully";
MySerial::~MySerial()
m_SerialPort->clear(); //丢弃缓冲区中的所有字符, 同时终止挂起的读取或写入操作
m_SerialPort->close();
m_SerialPort->deleteLater();
bool MySerial::WriteToSerial(QByteArray cmd)
if(cmd.isEmpty()) return false;
// qDebug() << "[ == MySerial == ] Send Data:" << cmd.toHex();
this->m_SerialPort->clear();
this->m_SerialPort->write(cmd);
this->m_SerialPort->flush(); //尽可能多地从内部写缓冲区写入底层串口而不阻塞
this->m_SerialPort->waitForBytesWritten(10);
return true;
QByteArray MySerial::ReadFromSerial()
QByteArray readData;
this->m_SerialPort->waitForReadyRead(5);
readData.append(this->m_SerialPort->readAll());
while (this->m_SerialPort->waitForReadyRead(5)) readData.append(this->m_SerialPort->readAll());
if(readData.isEmpty()) return QByteArray();
// qDebug() << "[ == MySerial == ] Read Data:" << readData.toHex();
return readData;
void MySerial::closeSerial()
if(!m_SerialPort->isOpen()) return;
m_SerialPort->clear();
m_SerialPort->close();
以上是关于读写串口 类QSerialPort的主要内容,如果未能解决你的问题,请参考以下文章