<QT学习>QT中串口QSerialport类学习与使用
QT5中已经增加了串口类QSrialPort,可以直接调用API函数进行快速开发。

注意qmake那边:QT += serialport。要把QT += serialport在加到.pro文件中
1. 获取串口信息
Dialog::Dialog(QWidget *parent) : QDialog(parent) { const auto infos = QSerialPortInfo::availablePorts(); for (const QSerialPortInfo &info : infos) serialPortComboBox->addItem(info.portName()); }
- QSerialPortInfo::availablePorts()

函数的功能时会检测当前电脑上串行端口,并且返回系统上串行端口的信息。
之后将获取到的信息加入Qcombobox下拉选项框中。本例中只添加了串口的名字即COM4。
2.设置串口参数并开启串口
void Dialog::openSerial() { if(runButton->text() == tr("开启")) { serial = new QSerialPort(); //port name serial->setPortName(serialPortComboBox->currentText()); //open serial->open(QIODevice::ReadWrite); serial->setBaudRate(115200); serial->setDataBits(QSerialPort::Data8); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl);
/* 一定要写,不然串口接收不到数据 */ connect(serial, SIGNAL(readyRead()), this, SLOT(readParam())); runButton->setText("关闭"); } else { serial->clear(); serial->close(); serial->deleteLater(); runButton->setText("开启"); } }connect(serial, SIGNAL(readyRead()), this, SLOT(readParam()));
该函数是启动串口接收功能。即当串口有数据时,readyRead()信号就会被抛出。对应的readParam()即QT中所定义的槽就会被调用。
注意:
readyRead()信号是有数据就直接抛出,在实际数据交互中,往往一帧数据有很多字节。这意味着我们一帧数据数据会触发多次信号。应当在对数据进行操作时候对数据进行校验。
3.串口发送数据
serial->write(sendData);
sendData为QByteArray类所创建的对象,即数据缓存区。
4.串口接收数据
g_RecBuf.append(serial->readAll());

readAll函数会读取当前设备所有剩余数据,并将它作为字节数组返回。
以上实例源码:
dialog.cpp
#include "dialog.h"
#include <QDebug>
#include <QThread>
#include <QTimer>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
serialPortComboBox = new QComboBox();
readParaBox = new QComboBox();
writeParaBox = new QComboBox();
runButton = new QPushButton(tr("开启"));
readPara = new QPushButton(tr("读取参数"));
writePara = new QPushButton(tr("下发参数"));
onlyOneRead = new QPushButton(tr("一键读取"));
onlyOneWrite = new QPushButton(tr("一键下发"));
cmd = readFlag;
timer = new QTimer();
/* add comprot into combobox item */
const auto infos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : infos)
serialPortComboBox->addItem(info.portName());
readParaBox->addItem(tr("读取参数地址1"));
readParaBox->addItem(tr("读取参数地址2"));
readParaBox->addItem(tr("读取参数地址3"));
readParaBox->addItem(tr("读取参数地址4"));
readParaBox->addItem(tr("读取参数地址5"));
writeParaBox->addItem(tr("下发参数地址1"));
writeParaBox->addItem(tr("下发参数地址2"));
writeParaBox->addItem(tr("下发参数地址3"));
writeParaBox->addItem(tr("下发参数地址4"));
writeParaBox->addItem(tr("下发参数地址5"));
auto mainLayout = new QGridLayout;
mainLayout->addWidget(serialPortComboBox, 0, 0);
mainLayout->addWidget(runButton, 0, 1);
mainLayout->addWidget(readParaBox,1,0);
mainLayout->addWidget(readPara, 1, 1);
mainLayout->addWidget(writeParaBox,2,0);
mainLayout->addWidget(writePara, 2, 1);
mainLayout->addWidget(onlyOneRead,3,0);
mainLayout->addWidget(onlyOneWrite,3,1);
setLayout(mainLayout);
connect(runButton, &QPushButton::clicked, this, &Dialog::openSerial);
connect(readPara, &QPushButton::clicked, this, &Dialog::sendCmd);
connect(writePara, &QPushButton::clicked, this, &Dialog::writeParam);
connect(timer, SIGNAL(timeout()), this, SLOT(timerStop()));
connect(onlyOneRead,&QPushButton::clicked,this,&Dialog::oneRead);
connect(onlyOneWrite,&QPushButton::clicked,this,&Dialog::oneWrite);
}
void Dialog::openSerial()
{
if(runButton->text() == tr("开启"))
{
serial = new QSerialPort();
//port name
serial->setPortName(serialPortComboBox->currentText());
//open
serial->open(QIODevice::ReadWrite);
serial->setBaudRate(115200);
serial->setDataBits(QSerialPort::Data8);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
connect(serial, SIGNAL(readyRead()), this, SLOT(readParam()));
runButton->setText("关闭");
}
else
{
serial->clear();
serial->close();
serial->deleteLater();
runButton->setText("开启");
}
}
void Dialog::writeParam(void)
{
QByteArray sendData;
sendData.resize(1026);
QString strWriteFile = writeParaBox->currentText();
strWriteFile.append(".dat");
if(strWriteFile == "下发参数地址1.dat")
{
file.setFileName("读取参数地址1.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址2.dat")
{
file.setFileName("读取参数地址2.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址3.dat")
{
file.setFileName("读取参数地址3.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址4.dat")
{
file.setFileName("读取参数地址4.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址5.dat")
{
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
file.close();
sendData.clear();
}
void Dialog::timerStop(void)
{
g_RecBuf.prepend(0xBB);
timer->stop();
{
QByteArray leftAck = g_RecBuf.left(2);
QByteArray rightAck = g_RecBuf.right(1);
QByteArray byte1;
QByteArray byte2;
byte1.append(0xBB);
byte1.append(0xAA);
byte2.append(0xFF);
if(g_RecBuf.size() > 30)
{
Dialog::saveDataToFile(g_RecBuf);
}
else if(leftAck == byte1 && rightAck == byte2 && cmd == writeFlag)
{
cmd = readFlag;
msglabel = new QLabel();
QMessageBox::question(this,tr("提示"),tr("下发参数成功"), QMessageBox::Ok);
}
}
g_RecBuf.clear();
}
void Dialog::readParam()
{
timer->start(100);
g_RecBuf.append(serial->readAll());
}
/* Function: Dialog::saveDataToFile
* Describe: Save the data from serial into File
*/
void Dialog::saveDataToFile(QByteArray &data)
{
if(cmd == readFlag)
{
QString strFileName = readParaBox->currentText();
file.setFileName(strFileName.append(".dat"));
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
}
if(cmd != readFlag)
{
switch (cmd) {
case cmd1:
file.setFileName("读取参数地址1.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break;
case cmd2:
file.setFileName("读取参数地址2.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break;
case cmd3:
file.setFileName("读取参数地址3.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break;
case cmd4:
file.setFileName("读取参数地址4.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break;
case cmd5:
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
cmd = readFlag;
break;
default:
break;
}
}
}
void Dialog::sendCmd(void)
{
QByteArray sendpara;
unsigned char zero = 0x00;
if(readParaBox->currentText() == tr("读取参数地址1"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x01);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址2"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x02);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址3"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x03);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址4"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x04);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址5"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x05);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
serial->write(sendpara);
sendpara.clear();
}
void Dialog::oneRead(void)
{
QByteArray cmdArray;
unsigned char zero = 0x00;
switch (cmd) {
case readFlag:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x01);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd1;
serial->write(cmdArray);
cmdArray.clear();
break;
case cmd1:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x02);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd2;
serial->write(cmdArray);
cmdArray.clear();
break;
case cmd2:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x03);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd3;
serial->write(cmdArray);
cmdArray.clear();
break;
case cmd3:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x04);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd4;
serial->write(cmdArray);
cmdArray.clear();
break;
case cmd4:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x05);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd5;
serial->write(cmdArray);
cmdArray.clear();
break;
}
}
void Dialog::oneWrite(void)
{
QByteArray sendData;
sendData.resize(1026);
file.setFileName("读取参数地址1.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
file.setFileName("读取参数地址2.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
file.setFileName("读取参数地址3.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
file.setFileName("读取参数地址4.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
#if 0
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
#endif
cmd = writeFlag;
}
Dialog::~Dialog()
{
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QComboBox>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTimer>
#include <QMessageBox>
enum enumType
{
readFlag,
cmd1,
cmd2,
cmd3,
cmd4,
cmd5,
writeFlag
};
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void openSerial(void);
void writeParam(void);
void sendCmd(void);
void timerStop(void);
void readParam(void);
void oneRead(void);
void oneWrite(void);
private:
void saveDataToFile(QByteArray &data);
private:
QComboBox *serialPortComboBox;
QComboBox *readParaBox;
QComboBox *writeParaBox;
QPushButton *runButton;
QPushButton *readPara;
QPushButton *writePara;
QPushButton *onlyOneRead;
QPushButton *onlyOneWrite;
QLabel *msglabel;
QSerialPort *serial;
QTimer *timer;
QFile file;
QByteArray g_RecBuf;
unsigned int Flag;
enumType cmd;
};
#endif // DIALOG_H
运行效果:

作用就是通过串口发送以及接收一些数据。
浙公网安备 33010602011771号