虽然现在大多数的家用PC机上已经不提供RS232接口了。但是由于RS232串口操作简单、通讯可靠,在工业领域中仍然有大量的应用。Qt以前的版本中,没有提供官方的对RS232串口的支持,编写串口程序很不方便。现在好了,在 Qt5.1 中提供了QtSerialPort模块,方便编程人员快速的开发应用串口的应用程序。 本文就简单的讲讲QtSerialPort模块的使用。
当前的QtSerialPort模块中提供了两个C++类,分别是QSerialPort 和QSerialPortInfo。
QSerialPort 类提供了操作串口的各种接口。
QSerialPortInfo 是一个辅助类,可以提供计算机中可用串口的各种信息。
使用方法
先介绍 QSerialPortInfo 的使用。下面是一个简单的例子,用来列举出电脑上全部的串口设备。
首先,需要在pro文件中增加如下内容:
QT += serialport
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 : “COM1”
Description : “通信端口”
Manufacturer: “(标准端口类型)”
Serial Number: “”
System Location: “\.\COM1”
Name : “COM5”
Description : “USB Serial Port”
Manufacturer: “FTDI”
Serial Number: “A400G3UXA”
System Location: “\.\COM5”
通常,我们需要指定程序使用某一个确定的串口,这时不能只使用串口名称,因为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();
}
QSerialPort 负责具体的串口操作。选定串口后,要先打开串口,才能设置波特率等参数。这些参数都设置好了就可以使用了。最基本的操作无非是read() 和 write()。需要注意的是这两个操作都是非阻塞的。
另外有一个重要的signal 也需要用到,那就是 void QIODevice::readyRead()
每次串口收到数据后都会发出这个signal。我们的程序中需要定义一个slot,并将其与这个signal 相连接。这样,每次新数据到来后,我们就可以在slot中读取数据了。这时一定要将串口缓冲区中的数据全部读出来,可以利用readAll() 来实现。
下面的代码片段给出了设置串口的例子。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QCoreApplication>
#include <QDialog>
#include <QString>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow(const QSerialPortInfo &info);
~MainWindow();
public slots:
void ReadyReadSlot();
private:
QSerialPort m_reader;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(const QSerialPortInfo &info)
{
m_reader.setPort(info);
if(m_reader.open(QIODevice::ReadWrite))
{
qDebug()<<"m_reader.open(QIODevice::ReadWrite)";
m_reader.setBaudRate(QSerialPort::Baud9600);
m_reader.setParity(QSerialPort::NoParity);
m_reader.setDataBits(QSerialPort::Data8);
m_reader.setStopBits(QSerialPort::OneStop);
m_reader.setFlowControl(QSerialPort::NoFlowControl);
m_reader.clearError();
m_reader.clear();
connect(&m_reader,&QSerialPort::readyRead, this, &MainWindow::ReadyReadSlot);
}
}
MainWindow::~MainWindow()
{
}
void MainWindow::ReadyReadSlot()
{
QByteArray arr = m_reader.readAll();
qDebug()<<arr;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSerialPortInfo com_info;
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
if(info.productIdentifier() == 29987)
{
com_info = info;
break;
}
}
qDebug()<<"Name : "<<com_info.portName();
qDebug()<<"Description : "<<com_info.description();
qDebug()<<"Manufacturer: "<<com_info.manufacturer();
qDebug()<<"Serial Number : "<<com_info.serialNumber();
qDebug()<<"System Location: "<<com_info.systemLocation();
qDebug()<<"productIdentifier: "<<com_info.productIdentifier();
MainWindow* window = new MainWindow(com_info);
window->show();
return a.exec();
}