<QT之Bug制造机>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();
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”的学习笔记的更多相关文章
- Qt 串口类QSerialPort 使用笔记
Qt 串口类QSerialPort 使用笔记 虽然现在大多数的家用PC机上已经不提供RS232接口了.但是由于RS232串口操作简单.通讯可靠,在工业领域中仍然有大量的应用.Qt以前的版本中,没有提供 ...
- c++中的类(class)-----笔记(类模板)
1,一个模板类至少具有一个类参数,类参数是个符号以表示将要被某个确定数据类型代替的类型. #include<iostream> #include<string> using n ...
- c++中的类(class)-----笔记(类继承)
1,派生类继承了基类的所有成员函数和数据成员(构造函数.析构函数和操作符重载函数外). 2,当不指明继承方式时,默认为私有继承. 3,基类的私有成员仅在基类中可见,在派生类中是不可见的.基类的私有成员 ...
- javascript类和原型学习笔记
js中类的所有实例对象都从同一个原型对象上继承属性.我们可以自己写一个对象创建的工厂方法来来"模拟"这种继承行为: //inherit()返回一个继承自原型对象p的属性的性对象 / ...
- Delphi中Chrome Chromium、Cef3学习笔记(三)
原文 http://blog.csdn.net/xtfnpgy/article/details/46635871 Delphi与JS的交互问题: 一.执行简单的JS 上一篇已经讲过: chrm ...
- C#同步,异步的理解,包括5.0中await和async(学习笔记)
之前在工作中一直用的是同步线程,就是先进入画面的load事件,然后在里面进行数据库调用的处理.后面又遇到了公司软件中一些比较古老的代码,一开始在那块古老代码中增加机能的时候,我想用到数据库的数据给画面 ...
- java中File类的相关学习
File类 1.关于系统路径分割符. 在Windows中,使用反斜杠“\”作为路径分割符,比如“c:\test”,但是java中反斜杠表示转义,所以需要用“C:\\test”在程序中来表示路径.还可以 ...
- c++中的类(class)-----笔记(类多态)
1,多态是一种运行期绑定机制,通过这种机制,实现将函数名绑定到函数具体实现代码的目的.一个函数的名称与其入口地址是紧密相连的,入口地址是该函数在内存中的起始地址.如果对一个函数的绑定发生在运行时刻而非 ...
- c++中的类(class)-----笔记(类简介)
1, class 和 struct 都可以定义一个类,区别是两者在所支持的 默认信息隐藏方式不同:c++ 中默认为 private 类型,而 struct 中默认为 public 类型. 2,类的私有 ...
随机推荐
- Android中设置半个屏幕大小且居中的button布局 (layout_weight属性)
先看例如以下布局 :
- 可能是东半球最全的RxJava使用场景小结
一.Scheduler线程切换 这样的场景常常会在"后台线程取数据,主线程展示"的模式中看见 Observable.just(1, 2, 3, 4) .subscribeOn(Sc ...
- Java transientkeyword使用小记
1. transient的作用及用法 我们都知道一个对象仅仅要实现了Serilizable接口,这个对象就能够被序列化,java的这样的序列化模式为开发人员提供了非常多便利.我们能够不必关系详细序列化 ...
- 纳德拉再造微软:市值如何重回第一阵营(思维确实变了,不再是以windows为中心,拥抱其它各种平台,敢在主战场之外找到适合自己的新战场)
有人说,现在的美国硅谷充满了“咖喱味”.也有人说,硅谷已经变成“印度谷”.原因就在于,以微软CEO萨提亚·纳德拉.谷歌CEO桑达尔·皮查伊为代表的印度人,近年以来掌控了全世界最令人望而生畏的科技巨头. ...
- jsp出现错误can not find the tag directory /web-inf/tags
百度google了一大圈没找到中文答案,无奈之下硬着头皮看了一个英文答案http://stackoverflow.com/questions/11502703/eclipse-can-not-find ...
- Xfce4里添加登录后程序自动运行
Xfce4里添加登录后程序自动运行 (注意该方法在登录桌面环境后才会自动运行程序. 在XUbuntu下测试过, Ubuntu下应该是类似的) 方法1: 找到这个东西, 自动添加一下 方法2: 在 .c ...
- Lamp安装 php-v5.6【ZendGuardLoader】的问题
Lamp安装 php-v5.6[ZendGuardLoader]的问题 标签(空格分隔):php,linux Apache日志: 就这个问题导致无法解析运行php文件.下面是网上找的解决方案 Zend ...
- Linux防火墙iptables介绍
介绍网络防火墙是通过一个或多个允许或拒绝的规则来过滤网络流量的网络设备或软件.网络防火墙还可以执行更复杂的任务,例如网络地址转换,带宽调整,提供加密隧道以及更多与网络流量相关的任务.而我们的任务就是需 ...
- git提交的规范
- iOS开发——打包报错error: linker command failed with exit code 1
真机运行没问题,打包报错: clang: error: linker command failed with exit code 1 (use -v to see invocation) 原因:在Xc ...