串口模块介绍
1、简介
在Qt的拓展模块中,Qt提供了许多的结果通讯模块,有串口、can、 ModBus等。下面就简单介绍一些Qt中的串口模块。
Qt串口提供基本功能,包括配置、I/O操作、获取和设置RS-232引脚的控制信号。
Qt串口模块不支持以下功能:
-
终端功能,如回声、控制CR/LF等。
-
文本模式。
-
配置读取或写入时的超时和延迟。
-
引脚输出信号更改通知。
-
特殊收发器条件,如帧错误、奇偶校验错误和中断条件错误。
2、包含类
在Qt串口模块中主要使用的类有两个:
QSerialPort | 提供访问串行端口的功能 |
---|---|
QSerialPortInfo | 提供有关现有串行端口的信息 |
串口模块使用
串口的使用步骤如下:
1、在项目中引入串口模块
cpp
QT += serialport
2、添加串口类相关头文件
#include <QSerialPort>
cpp
#include <QSerialPortInfo>
3、使用QSerialPortInfo中的静态文件获取设备中的串口信息。availablePorts()函数返回的是一个串口信息的列表。
cpp
foreach(const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) { //读取串口信息
m_serialPort->setPort(Info);
if( m_serialPort->open(QIODevice::ReadWrite) ) {
portnames.append(Info.portName());
m_serialPort->close();
}
}
4、创建一个QSerialPort类对象,使用通过availablePorts()函数获取的串口信息,设置需要打开的串口号、波特率、校验位等一些串口信息。设置的函数如下:
bool | setBaudRate(qint32 baudRate , QSerialPort::Directions directions = AllDirections) | 设置波特率 |
---|---|---|
bool | setBreakEnabled(bool set = true) | |
bool | setDataBits(QSerialPort::DataBits dataBits) | 设置数据位 |
bool | setDataTerminalReady(bool set) | |
bool | setFlowControl(QSerialPort::FlowControl flowControl) | 设置流量控制模式 |
bool | setParity(QSerialPort::Parity parity) | 设置校验模式 |
void | setPort(const QSerialPortInfo &serialPortInfo) | |
void | setPortName(const QString &name) | 设置串口号 |
void | setReadBufferSize(qint64 size) | 设置读写缓存区大小 |
bool | setRequestToSend(bool set) | 设置保持线路信号RTS的状态(高或低) |
bool | setStopBits(QSerialPort::StopBits stopBits) | 设置停止位 |
5、设置完各种参数之后就可以打开串口了,打开串口使用serialPort类中的open函数。此函数需要传入一个权限控制:读、写、读写等。
cpp
bool MySerialPort::openSeriaPort(QSerialPort::OpenMode openmode){
return m_serialPort->open(openmode);
}
6、在Qt中使用QSerialPort::readyRead信号通知程序有数据上来。之后程序在使用readAll()函数获取缓存区中数据。
cpp
connect(m_serialPort,&QSerialPort::readyRead,[=]()
{
qDebug() << "MySerialPort createSeriaPort readDate";
readDate();
});
cpp
void MySerialPort::readDate(){
QByteArray data = m_serialPort->readAll();
emit haveReceive(data);
}
7、Qt串口模块中使用QSerialPort中的write函数写入数据,并发送。
cpp
qint64 MySerialPort::writeDate(QByteArray data,int len){
return m_serialPort->write(data,len);
}
至此,Qt中串口的基础使用已经完成,可以进行串口数据交互了,
例子
一下自己是一个简单的串口使用Demo。
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTextBrowser>
#include <QLineEdit>
#include "myserialport.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QSerialPort *serial;
QLineEdit *fasong;
QTextBrowser *jieshou;
MySerialPort serialPort;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_comboBox_currentTextChanged(const QString &arg1);
void on_comboBox_2_currentTextChanged(const QString &arg1);
void readBytes(QByteArray data);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>
#include <QSerialPort>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
qDebug() << "主窗口构造函数";
fasong = ui->fasong;
jieshou = ui->jieshou;
serialPort.createSeriaPort(QSerialPort::Data8,QSerialPort::NoParity,QSerialPort::OneStop,QSerialPort::NoFlowControl);
connect(&serialPort,&MySerialPort::haveReceive,this,&MainWindow::readBytes);
QStringList lists = serialPort.getPortNames();
foreach (QString str, lists) {
ui->comboBox->addItem(str);
}
ui->comboBox_2->addItem("1200");
ui->comboBox_2->addItem("2400");
ui->comboBox_2->addItem("4800");
ui->comboBox_2->addItem("9600");
ui->comboBox_2->addItem("19200");
}
MainWindow::~MainWindow()
{
delete ui;
serialPort.closeSeriaPort();
}
void MainWindow::on_pushButton_clicked()
{
qDebug() << "发送数据" ;
QByteArray data = fasong->displayText().toUtf8();
int len = data.length();
serialPort.writeDate(data,len); //串口发数据
}
//cpp
void MainWindow::readBytes(QByteArray data) {
qDebug() << "接收数据" ;
jieshou->setText(data);
}
void MainWindow::on_pushButton_2_clicked()
{
//打开串口
if(!serialPort.openSeriaPort(QIODevice::ReadWrite))
{
qDebug() << "串口打开失败" ;
}
}
void MainWindow::on_comboBox_currentTextChanged(const QString &arg1)
{
serialPort.setPortName(arg1);
}
void MainWindow::on_comboBox_2_currentTextChanged(const QString &arg1)
{
//设置波特率
serialPort.setBaudRate(arg1.toInt());
}
cpp
/***************************************************************
* 文件名称: MySerialPort
* 文件功能: 封装qt中的串口创建
* 开发时间:
* 开发人:
***************************************************************/
#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QObject>
class MySerialPort : public QObject
{
Q_OBJECT
public:
/**
* @brief MySerialPort 构造函数,没有具体意义
* @param parent
*/
MySerialPort(QObject *parent = nullptr);
/**
* @brief ~MySerialPort 析构函数,用于释放new 的串口实例
*/
virtual ~MySerialPort();
/**
* @brief createSeriaPort 用于创建串口对象
* @param dataBits 数据位数
* @param parity 奇偶校验
* @param stopBits 停止位数
* @param flowControl 流量控制
* @return
*/
bool createSeriaPort(QSerialPort::DataBits dataBits,QSerialPort::Parity parity,QSerialPort::StopBits stopBits,QSerialPort::FlowControl flowControl);
/**
* @brief readDate 读取数据,此函数会发送一个带参数的信号
*/
void readDate();
/**
* @brief writeDate 发送数据
* @param data 想要发送的数据
* @param len 想要发送数据的长度
* @return 是否发送成功
*/
qint64 writeDate(QByteArray data,int len);
/**
* @brief setPortName 设置端口号
* @param portName 端口号
*/
void setPortName(QString portName);
/**
* @brief setBaudRate 设置波特率
* @param baudRate 波特率
* @return
*/
bool setBaudRate(int baudRate);
/**
* @brief getPortNames 获取当前系统中可用的串口
* @return 返回值为一个字符串列表
*/
QStringList getPortNames();
/**
* @brief openSeriaPort 打开串口
* @param openmode 打开串口模式
* @return
*/
bool openSeriaPort(QSerialPort::OpenMode openmode);
/**
* @brief closeSeriaPort 关闭串口
*/
void closeSeriaPort();
signals:
/**
* @brief haveReceive 向外部发送接收串口数据的函数
* @param data
*/
void haveReceive(QByteArray data);
private:
QSerialPort * m_serialPort = nullptr;
};
#endif // MYSERIALPORT_H
cpp
#include "myserialport.h"
#include <QDebug>
MySerialPort::MySerialPort(QObject *parent):QObject(parent)
{
}
MySerialPort::~MySerialPort(){
if(m_serialPort != nullptr){
delete m_serialPort;
}
}
bool MySerialPort::createSeriaPort(QSerialPort::DataBits dataBits,QSerialPort::Parity parity,QSerialPort::StopBits stopBits,QSerialPort::FlowControl flowControl){
qDebug() << "MySerialPort createSeriaPort";
m_serialPort = new QSerialPort();
m_serialPort->setDataBits(dataBits);
m_serialPort->setParity(parity);
m_serialPort->setStopBits(stopBits);
m_serialPort->setFlowControl(flowControl);
connect(m_serialPort,&QSerialPort::readyRead,[=]()
{
qDebug() << "MySerialPort createSeriaPort readDate";
readDate();
});
return true;
}
void MySerialPort::readDate(){
QByteArray data = m_serialPort->readAll();
emit haveReceive(data);
}
qint64 MySerialPort::writeDate(QByteArray data,int len){
return m_serialPort->write(data,len);
}
void MySerialPort::setPortName(QString portName){
m_serialPort->setPortName(portName);
}
bool MySerialPort::setBaudRate(int baudRate){
return m_serialPort->setBaudRate(baudRate);
}
QStringList MySerialPort::getPortNames(){
QStringList portnames;
if(m_serialPort == nullptr){
return portnames;
}
foreach(const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) { //读取串口信息
m_serialPort->setPort(Info);
if( m_serialPort->open(QIODevice::ReadWrite) ) {
portnames.append(Info.portName());
m_serialPort->close();
}
}
return portnames;
}
bool MySerialPort::openSeriaPort(QSerialPort::OpenMode openmode){
return m_serialPort->open(openmode);
}
void MySerialPort::closeSeriaPort(){
m_serialPort->close();
}