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();
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

  运行效果:

  作用就是通过串口发送以及接收一些数据。



<QT之Bug制造机>QT中串口类“QSerialPort”的学习笔记的更多相关文章

  1. Qt 串口类QSerialPort 使用笔记

    Qt 串口类QSerialPort 使用笔记 虽然现在大多数的家用PC机上已经不提供RS232接口了.但是由于RS232串口操作简单.通讯可靠,在工业领域中仍然有大量的应用.Qt以前的版本中,没有提供 ...

  2. c++中的类(class)-----笔记(类模板)

    1,一个模板类至少具有一个类参数,类参数是个符号以表示将要被某个确定数据类型代替的类型. #include<iostream> #include<string> using n ...

  3. c++中的类(class)-----笔记(类继承)

    1,派生类继承了基类的所有成员函数和数据成员(构造函数.析构函数和操作符重载函数外). 2,当不指明继承方式时,默认为私有继承. 3,基类的私有成员仅在基类中可见,在派生类中是不可见的.基类的私有成员 ...

  4. javascript类和原型学习笔记

    js中类的所有实例对象都从同一个原型对象上继承属性.我们可以自己写一个对象创建的工厂方法来来"模拟"这种继承行为: //inherit()返回一个继承自原型对象p的属性的性对象 / ...

  5. Delphi中Chrome Chromium、Cef3学习笔记(三)

    原文   http://blog.csdn.net/xtfnpgy/article/details/46635871   Delphi与JS的交互问题: 一.执行简单的JS 上一篇已经讲过: chrm ...

  6. C#同步,异步的理解,包括5.0中await和async(学习笔记)

    之前在工作中一直用的是同步线程,就是先进入画面的load事件,然后在里面进行数据库调用的处理.后面又遇到了公司软件中一些比较古老的代码,一开始在那块古老代码中增加机能的时候,我想用到数据库的数据给画面 ...

  7. java中File类的相关学习

    File类 1.关于系统路径分割符. 在Windows中,使用反斜杠“\”作为路径分割符,比如“c:\test”,但是java中反斜杠表示转义,所以需要用“C:\\test”在程序中来表示路径.还可以 ...

  8. c++中的类(class)-----笔记(类多态)

    1,多态是一种运行期绑定机制,通过这种机制,实现将函数名绑定到函数具体实现代码的目的.一个函数的名称与其入口地址是紧密相连的,入口地址是该函数在内存中的起始地址.如果对一个函数的绑定发生在运行时刻而非 ...

  9. c++中的类(class)-----笔记(类简介)

    1, class 和 struct 都可以定义一个类,区别是两者在所支持的 默认信息隐藏方式不同:c++ 中默认为 private 类型,而 struct 中默认为 public 类型. 2,类的私有 ...

随机推荐

  1. 面试题——ArrayList和LinkedList的区别

    List概括 先回顾一下List在Collection的框架图: 从图中可以看出: List是一个接口,他继承Collection接口,代表有序的队列. AbstractList是一个抽象类, ,它继 ...

  2. HTTP Analyzer(实时分析HTTP/HTTPS数据流)

    简述 HTTP Analyzer是一款实时分析HTTP/HTTPS数据流的工具.它可以实时捕捉HTTP/HTTPS协议数据,可以显示许多信息(包括:文件头.内容.Cookie.查询字符窜.提交的数据. ...

  3. vim 常用变量

    为了vim更好的支持python写代码,修改tab默认4个空格有两种设置方法: 1. vim /etc/vimrc 1 set ts=4 2 set sw = 4 2. vim /etc/vimrc ...

  4. 如何成为一个偷懒又高效的Android开发人员

    我敢肯定你对这个标题肯定心存疑惑,但事实就是如此,这个标题完全适合Android开发人员.据我所知, Android程序员不情愿写 findViewById().点击事件监听等重复率较高的代码.那我们 ...

  5. [Transducer] Make an Into Helper to Remove Boilerplate and Simplify our Transduce API

    Our transduce function is powerful but requires a lot of boilerplate. It would be nice if we had a w ...

  6. 好记性不如烂笔头86-spring3学习(7)-ApplicationContext中bean的生命周期

    假设使用ApplicationContext来生成.管理Bean, 一个Bean从建立到销毁,会历经几个运行阶段. 我个人理解一般的bean的生命周期主要包含:建立,初始化,使用阶段,销毁四个核心阶段 ...

  7. php中file_get_contents如何读取大容量文件

    php中file_get_contents如何读取大容量文件 一.总结 一句话总结:使用file_get_contents()进行分段读取,file_get_contents()函数可以分段读取 1. ...

  8. CUDA中的归约

    CUDA编程实战书中的乘方和解决办法: 对一个数组执行某种计算,然后产生一个更小的结果数组. 由一个线程在共享内存上进行迭代并计算出总和值.而如果用并行,所花时间就与数组长度的对数成正比. 代码的思想 ...

  9. PostgreSQL相关总结

    源码安装PostgreSQL总结 简明安装步骤(其中prefix指定PostgreSQL的安装目录,该目录与数据目录pgdata和PostgreSQL的源代码包目录均无关) yum -y instal ...

  10. UI Framework-1: Aura Graphics Architecture

    Graphics Architecture Overview Each Aura Window owns a corresponding compositor layer. The layer tre ...