开发目的:使用QT进行串口通信数据传输测试,程序能打开指定串口进行数据的收发。
开发环境:小米笔记本+win10+qt5.14.2+虚拟串口驱动+友善串口调试助手
开发步骤:
1、安装虚拟串口驱动软件,Virtual Serial Port Driver,测试安装版本为6.9,打开虚拟串口程序后,新建一对虚拟的串口COM3和COM4,相当于是在笔记本电脑上虚拟出来两个串口COM3和COM4进行通信,QT程序打开COM3后发送数据,友善串口助手打开COM4可以显示接收到COM3收到的数据并显示。
2、安装友善串口调试助手软件,目的是串口数据接收显示和发回数据到QT程序。
3、编写QT相关界面和代码如下:
3.1: 项目.pro文件第一行新增 serialport 引用
QT += core gui serialport
3.2:头文件.h文件代码如下:
#ifndef FORMPORTSETTING_H
#define FORMPORTSETTING_H
#include
//包含头文件
#include //提供访问串口的功能
#include //提供系统中存在的串口的信息
#include
#include
#include
#include
namespace Ui {
class FormPortSetting;
}
class FormPortSetting : public QWidget
{
Q_OBJECT
public:
explicit FormPortSetting(QWidget *parent = nullptr);
~FormPortSetting();
private slots:
void on_btnOpen_clicked();
void on_btnSend_clicked();
void on_btnClear_clicked();
void ReadSerial();
void OpenSerial();
void CloseSerial();
void ScanSerialPort();
void on_btnSearch_clicked();
void on_btnRefresh_clicked();
private:
Ui::FormPortSetting *ui;
//创建定时器对象
QTimer *scanPortTimer;
//创建串口对象
QSerialPort* mySerialPort;
};
#endif // FORMPORTSETTING_H
3.3:.cpp文件代码如下:
#include "formportsetting.h"
#include "ui_formportsetting.h"
FormPortSetting::FormPortSetting(QWidget *parent) :
QWidget(parent),
ui(new Ui::FormPortSetting)
{
ui->setupUi(this);
//将代码实现的功能显示在ui界面里面,这就是为啥刚才改名字。
scanPortTimer = new QTimer(this);
connect(scanPortTimer,SIGNAL(timeout()),this,SLOT(ScanSerialPort()));
scanPortTimer->start(5000);
ScanSerialPort();
//设置串口名
ui->cboPortList->setCurrentText("COM3");
//设置波特率
ui->cboBaudRate->setCurrentText("9600");
//设置数据位数
ui->cboDataBits->setCurrentIndex(3);
//设置奇偶校验
ui->cboStopBits->setCurrentIndex(0);
//设置停止位
ui->cboParity->setCurrentIndex(0);
mySerialPort = new QSerialPort(this);
connect(mySerialPort,SIGNAL(readyRead()),this,SLOT(ReadSerial()));
}
FormPortSetting::~FormPortSetting()
{
delete ui;
}
void FormPortSetting::ScanSerialPort()
{
ui->cboPortList->clear();
//通过QSerialPortInfo查找可用串口
QList infos = QSerialPortInfo::availablePorts();
ui->cboPortList->clear();
if(infos.isEmpty())
{
ui->cboPortList->addItem("无");
}
else
{
foreach (QSerialPortInfo info, infos)
{
ui->cboPortList->addItem(info.portName());
}
}
}
void FormPortSetting::on_btnOpen_clicked()
{
//根据按钮的值判断后续操作
if( ui->btnOpen->text() == "打开" )
{
if(scanPortTimer->isActive())
{
scanPortTimer->stop();
}
OpenSerial();
}
else if ( ui->btnOpen->text() == "关闭")
{
CloseSerial();
if(!scanPortTimer->isActive())
{
scanPortTimer->start(5000);
}
}
}
void FormPortSetting::CloseSerial()
{
//关闭串口
mySerialPort->close();
//下拉菜单控件使能
ui->cboPortList->setEnabled(true);
ui->cboBaudRate->setEnabled(true);
ui->cboDataBits->setEnabled(true);
ui->cboStopBits->setEnabled(true);
ui->cboParity->setEnabled(true);
ui->cboFlow->setEnabled(true);
ui->btnOpen->setText(QString("打开"));
//发送按键失能
ui->btnSend->setEnabled(false);
}
void FormPortSetting::OpenSerial()
{
QSerialPort::BaudRate baudRate;//定义波特率
QSerialPort::DataBits dataBits;//定义数据位
QSerialPort::StopBits stopbits;//定义停止位
QSerialPort::Parity checkbits;//定义校验位
if(ui->cboBaudRate->currentText() == "4800")
{
baudRate = QSerialPort::Baud4800;
}
else if(ui->cboBaudRate->currentText() == "9600")
{
baudRate = QSerialPort::Baud9600;
}
else if(ui->cboBaudRate->currentText() == "115200")
{
baudRate = QSerialPort::Baud115200;//如果选择了某个波特率,波特率就会设置为这个数值。
}
if(ui->cboDataBits->currentText() == "5")
{
dataBits = QSerialPort::Data5;
}
else if(ui->cboDataBits->currentText() == "6")
{
dataBits = QSerialPort::Data6;
}
else if(ui->cboDataBits->currentText() == "7")
{
dataBits = QSerialPort::Data7;
}
else if(ui->cboDataBits->currentText() == "8")
{
dataBits = QSerialPort::Data8;//如果选择了某个数据位,波特率就会设置为这个数值。
}
if(ui->cboStopBits->currentText() == "1")
{
stopbits = QSerialPort::OneStop;
}
else if(ui->cboStopBits->currentText() == "1.5")
{
stopbits = QSerialPort::OneStop;
}
else if(ui->cboStopBits->currentText() == "2")
{
stopbits = QSerialPort::TwoStop;//如果选择了某个停止位,波特率就会设置为这个数值。
}
if(ui->cboParity->currentText()=="None")
{
checkbits = QSerialPort::NoParity;//如果选择了某个校验位,波特率就会设置为这个数值。
}
if(ui->cboFlow->currentText()=="None")
{
//设置流控制
mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
}
mySerialPort->setPortName(ui->cboPortList->currentText());//设置串口的全部信息
mySerialPort->setBaudRate(baudRate);//设置波特率
mySerialPort->setDataBits(dataBits);//设置数据位数
mySerialPort->setStopBits(stopbits);//设置停止位
mySerialPort->setParity(checkbits);//设置奇偶校验
if(mySerialPort->open(QIODevice::ReadWrite)== true)
{
QMessageBox::information(this ,"提示","串口打开成功");//配置提示信息
//下拉菜单控件使能
ui->cboPortList->setEnabled(false);
ui->cboBaudRate->setEnabled(false);
ui->cboDataBits->setEnabled(false);
ui->cboStopBits->setEnabled(false);
ui->cboParity->setEnabled(false);
ui->cboFlow->setEnabled(false);
ui->btnOpen->setText(QString("关闭"));
//发送按键生效
ui->btnSend->setEnabled(true);
}else
{
QMessageBox::critical(this ,"提示","串口打开失败");
}
//设置串口名
mySerialPort->setPortName(ui->cboPortList->currentText());
}
void FormPortSetting::on_btnSend_clicked()
{
//将发送栏的数据输出
long long sendNum=0;
long long a=0;
//字符串形式
if(ui->is16SendQch->checkState() == false)
{
//ASCII发送
a=mySerialPort->write(ui->txtSend->document()->toPlainText().toLocal8Bit().data());
}
else
{
//16进制发送(将16进制转换成Ascll码对应的字符发送)
a=mySerialPort->write(QByteArray::fromHex(ui->txtSend->document()->toPlainText().toUtf8()).data()); //16进制数据解码后发送
}
//如果发送成功,a获取发送的字节长度,发送失败则返回-1
if(a > 0)
{
sendNum += a;
QMessageBox::information(this ,"提示","发送成功");
}
else
{
QMessageBox::critical(this ,"提示","发送失败");
}
}
void FormPortSetting::on_btnClear_clicked()
{
//设置串口名
mySerialPort->setPortName("COM3");
//设置波特率
mySerialPort->setBaudRate(QSerialPort::Baud9600);
//设置数据位数
mySerialPort->setDataBits(QSerialPort::Data8);
//设置奇偶校验
mySerialPort->setParity(QSerialPort::NoParity);
//设置停止位
mySerialPort->setStopBits(QSerialPort::OneStop);
//设置流控制
mySerialPort->setFlowControl(QSerialPort::NoFlowControl);
//打开串口
mySerialPort->open(QIODevice::ReadWrite);
}
void FormPortSetting::ReadSerial()
{
//从接收缓冲区中读取数据
QByteArray buffer = mySerialPort->readAll();
//从界面中读取以前收到的数据
QString recv = ui->txtReceive->toPlainText();
recv += QString(buffer);
//清空以前的显示
ui->txtReceive->clear();
//重新显示
ui->txtReceive->append(recv);
}
void FormPortSetting::on_btnSearch_clicked()
{
ScanSerialPort();
}
void FormPortSetting::on_btnRefresh_clicked()
{
ScanSerialPort();
}
源码下载地址:https://download.csdn.net/download/xqf222/87499943