需要添加的内容
使用qt中的串口通信的时候需要用到的两个头文件分别为:
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
QSerialPort 类提供了操作串口的各种接口。
QSerialPortInfo 是一个辅助类,可以提供计算机中可用串口的各种信息
还需要在工程文件中加下面一行代码:
QT += serialport
代码
遍历可用的串口
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) //遍历可用的窗口
{
//QSerialPortInfo::availablePorts() 获取所有端口的信息,返回值是一个QList<QSerialPortInfo>
qDebug()<<"Name:"<<info.portName(); //返回串口名称
qDebug()<<"Description:"<<info.description(); //返回串口说明
qDebug() << "Manufacturer: " << info.manufacturer(); //返回制造商信息
qDebug() << "Serial Number: " << info.serialNumber(); //返回串口连接设备的串口序列号
/*通常,我们需要指定程序使用某一个确定的串口,这时不能只使用串口名称,因为USB串口每次插在不同
的USB口上时获得的串口名称都可能有变化。这时可以利用串口的序列号,这个号码一般来说是唯一的
*/
qDebug() << "System Location: " << info.systemLocation(); //系统本地位置
}
输出结果:
QSerialPort支持两种编程方法:
1)*异步(非阻塞)方式。当控制权返回到Qt的事件循环中,相应的操作就会被调度和执行。当操作执行完了QSerial就会触发一个信号。例如:
QSerialPort::write()方法返回。当数据发送到串口,QSerialPort就会触发bytesWirtten()。
(2)*同步(阻塞)方式。在非GUI和多线程应用程序中,我们可以调用waitFor...()函数(例如QSerialPort::waitForReadyRead())使得调用线程在完成之前都是阻塞的。
阻塞的串口编程与非阻塞的串口编程是不一样的。阻塞的串口不许要事件循环,需要的代码很少。然而,在一个GUI应用程序中,阻塞的串口操作应该仅仅在非GUI线程中使用,避免用户界面冻结
QSerialPort 的串口操作
选定串口后,要先打开串口,才能设置波特率等参数。这些参数都设置好了就可以使用了。最基本的操作无非是read() 和 write()。需要注意的是这两个操作都是非阻塞的
另外有一个重要的signal 也需要用到,那就是 void QIODevice::readyRead(),每次串口收到数据后都会发出这个signal。我们的程序中需要定义一个slot,并将其与这个signal 相连接。这样,每次新数据到来后,我们就可以在slot中读取数据了。这时一定要将串口缓冲区中的数据全部读出来,可以利用readAll() 来实现
读取串口数据实例--超声波测距仪
Win.cpp
#include "win.h"
Win::Win(QWidget *parent)
: QWidget(parent)
{
str1="";
i=0;
this->resize(500,300);
setWindowTitle("超声波测距仪- 明师软件");
serial = new QSerialPort;
label=new QLabel("距离:",this);
label->move(50,100);
label->setStyleSheet("font-size:50px;color:red;font-family:黑体 "); //设置字体大小,字体颜色,字体
label1=new QLabel("5 厘米",this);
label1->move(200,100);
label1->setStyleSheet("font-size:50px;color:red;font-family:黑体 ");
QSerialPortInfo com_info;
qDebug() << "Name : " << com_info.portName(); //串口名称默认是 ""
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
if( info.serialNumber() == "5573932333735170A1A2" ) //通过串口序列号来判断是否需要的设备
{
com_info = info;
break;
}
}
if (com_info.portName()==""){ //如果没找到超声波串口
QMessageBox::critical(this,"错误","请把超声波测距仪插入USB口",QMessageBox::Ok);
exit(0); //退出程序
}
serial->setPort(com_info); //设置要操作的串口
if(serial->open(QIODevice::ReadWrite)) //如果串口打开成功
//以读写方式打开串口
{
qDebug() << "成功打开串口";
serial->setBaudRate(QSerialPort::Baud9600); //设置波特率
/*常用波特率
常量 值 说明
QSerialPort::Baud1200 1200 1200 baud.
QSerialPort::Baud2400 2400 2400 baud.
QSerialPort::Baud4800 4800 4800 baud.
QSerialPort::Baud9600 9600 9600 baud.
QSerialPort::Baud19200 19200 19200 baud.
QSerialPort::Baud38400 38400 38400 baud.
QSerialPort::Baud57600 57600 57600 baud.
QSerialPort::Baud115200 115200 115200 baud.
*/
serial->setParity(QSerialPort::NoParity); //设置校验位
serial->setDataBits(QSerialPort::Data8); //设置数据位
serial->setStopBits(QSerialPort::OneStop); //设置停止位
serial->setFlowControl(QSerialPort::NoFlowControl); //设置流控制
//serial->clearError();
/*此属性保存串行端口的错误状态I/O设备状态返回错误代码。例如,如果open()返回false,或者读/写操作返回-1,
则可以使用此属性找出操作失败的原因。调用clearError()后,错误代码被设置为默认的QSerialPort::NoError
*/
//serial->clear();
/*
清除输出或输入缓冲区中的所有字符。这包括清除内部类缓冲区和UART(驱动程序)缓冲区。
同时终止挂起的读或写操作。如果成功,则返回true;否则返回false
*/
connect(serial, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); //如果接收到数据输入信号,就执行相应的槽函数
}
}
Win::~Win()
{
}
void Win::readyReadSlot()
{
QByteArray arr = serial->readAll(); //读取串口缓冲区数据
//读取后的数据类型:QByteArray
str = arr; //转换成QString
str1=str1+str;
i=str1.count("\r\n");//获取子串出现的次数
if(i>=2){
//qDebug() <<str1<<i;
list = str1.split("\r\n"); //把字符串拆分成QStringList
str=list[1]+"厘米";
label1->setText(str);
label1->adjustSize();// 根据内容自适应大小
str1="";
}
}
win.h
#ifndef WIN_H
#define WIN_H
#include <QWidget>
#include <QDebug>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QLabel>
#include <QMessageBox>
class Win : public QWidget
{
Q_OBJECT
public:
Win(QWidget *parent = nullptr);
~Win();
QSerialPort *serial; //定义一个全局的串口对象指针
QLabel* label;
QLabel* label1;
QString str;
QString str1;
int i;
QStringList list;
public slots:
void readyReadSlot();
};
#endif // WIN_H
工程下载:链接:https://pan.baidu.com/s/1meJqogbWZ-KDTqU52jw0rQ
提取码:6666