由于工作原因,需要设计一款串口测试软件,方便以后工作中各种仪表及设备的通讯测试,现在完成了初版软件。
1、首先需要安装虚拟串口软件,安装完毕后,配置虚拟串口3,串口4,相互对应。虚拟串口软件很好找,百度一下下载使用便可。
2、下面测试Qt串口软件与普通串口软件,之间发送数据进行通讯测试,左边Qt串口程序,右边普通串口程序
2.1 下面为qt发送字符串,普通串口接收。
2.2 下面为qt发送16进制,普通串口接收16进制。
2.3 下面为普通串口发送字符串,Qt串口接收字符串
2.4 下面为普通串口发送16进制,Qt串口接收16进制
下面附源码:
1、pro文件
#-------------------------------------------------
#
# Project created by QtCreator 2019-10-25T14:04:08
#
#-------------------------------------------------
QT += core gui
QT += widgets
#添加串口类
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = LFLCCS
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
2、mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include<QDebug>
#include <QObject>
#include<QString>
#include <QTimer>
#include<QChar>
#include <QByteArray>
#include <QDataStream>
#include <QVBoxLayout>
#include<QFile>
#include<QIODevice>
//目录相关
#include<QDir>
#include<QFileDialog>
#include<QTextStream>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//字符串转16进制
void StringToHex(QString str,QByteArray &senddata);
//字符转16进制
unsigned char ByteArrayToHexChar(unsigned char ch);
void on_clrearReceive_btn_clicked();
void on_sendMessage_btn_clicked();
void on_openSerial_btn_clicked();
void readData();
void on_closeSerial_btn_clicked();
void on_clearSend_btn_clicked();
void on_receiveToHex_ceb_stateChanged(int arg1);
void on_sendToHex_ceb_2_stateChanged(int arg1);
void on_receiveToHex_stateChanged(int arg1);
void on_sendToHex_2_stateChanged(int arg1);
void on_sendToHex_ceb_stateChanged(int arg1);
void on_saveReceiveMessage_btn_clicked();
private:
Ui::MainWindow *ui;
QSerialPort serial;
QVBoxLayout receiveVBL;
QString showStr;
int receiveHexState=0;
int sendHexState=0;
QString receiveHexString,sendHexString;
};
#endif // MAINWINDOW_H
3、main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
4、mainwindows.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ ui->setupUi(this);
ui->sendMessage_te->setFont(QFont("Timers",50,QFont::Bold));
//QVBoxLayout receiveVBL= new QVBoxLayout;
// QVBoxLayout.addWidget(receiveMessage_te);
// QVBoxLayout.addWidget(clrearReceive_btn);
}
MainWindow::~MainWindow()
{ delete ui;
}
//发送数据
void MainWindow::on_sendMessage_btn_clicked()
{
// QString str=ui->sendMessage_te->toPlainText();
// QByteArray senddata;
QByteArray senddata;
QString str =ui->sendMessage_te->toPlainText();
//获取字符串的长度
//isEmpty 空字符串返回真,否则返回假
if(!str.isEmpty()) {
int len=str.length();
//如果发送的数据个数为奇数,则在前面最后落单的字符前添加一个0
if(len %2==1)
{ //str=str.insert(len-1,'0');
}
if(sendHexState==1)
{ StringToHex(str,senddata);//将str转化为16进制的形式
serial.write(senddata);
}
else
{
//发送到串口
serial.write(str.toLatin1());
}
}
//11月8日代码
/*
//16进制发送
if(sendHexState==1)
{
// this->StringToHex(str,senddata);
// serial.write(senddata);
serial.write(ui->sendMessage_te->toPlainText().toLatin1());
}
else
{
serial.write(ui->sendMessage_te->toPlainText().toLatin1());
}
*/
}
//打开串口
void MainWindow::on_openSerial_btn_clicked()
{
// int numRead = 0, numReadTotal = 0;
// char buffer[50];
QByteArray receiveBuffer;
QString receiveStr;
serial.setPortName(this->ui->comSelect_cbb->currentText());
//波特率设置
serial.setBaudRate(this->ui->baudSelect_cbb->currentText().toInt());
//数据位
serial.setDataBits(QSerialPort::Data8);
//奇偶校验
serial.setParity(QSerialPort::NoParity);
//停止位
serial.setStopBits(QSerialPort::OneStop);
//流控
serial.setFlowControl(QSerialPort::NoFlowControl);
//打开串口
serial.open(QIODevice::ReadWrite);
//提示打开串口信息
qDebug()<<"open uart";
//开始时参照了QT帮助手册上的例子
/* while(1) {
//获取串口数据,并计算获取的数据数
numRead = serial.read(buffer, 50);
//计算获取的数据总数
numReadTotal += numRead;
if (numRead == 0 && (!serial.waitForReadyRead()))
break;
}
//输出串口信息
qDebug()<<buffer;
*/
//绑定信号和槽函数
QObject::connect(&serial,&QSerialPort::readyRead,this,&MainWindow::readData);
}
//关闭串口
void MainWindow::on_closeSerial_btn_clicked()
{
// serial.clear();
serial.close();
//输出串口信息
qDebug()<<"close uart";
}
void MainWindow::StringToHex(QString str, QByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen=0;
int len=str.length();
senddata.resize(len/2);
char lstr,hstr;
for(int i=0;i<len;)
{
hstr =str[i].toLatin1();
//去掉空格
if(hstr==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
lstr=str[i].toLatin1();
hexdata=ByteArrayToHexChar(hstr);
lowhexdata=ByteArrayToHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else
hexdata=hexdata*16+lowhexdata;
i++;
senddata[hexdatalen]=(char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
}
unsigned char MainWindow::ByteArrayToHexChar(unsigned char ch)
{
if ((ch >= '0') && (ch <= '9'))
return ch - 0x30;
else if ((ch >= 'A') && (ch <= 'F'))
return ch - 'A' + 10;
else if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
//无符号数返回
else return (-1);
}
void MainWindow::readData()
{
QByteArray buf;
QString temp;
static QString str=temp;
buf = serial.readAll();
if((!buf.isEmpty()))
{
qDebug()<<"输出字节buf:";
qDebug()<<buf;
//设置字体颜色及字体色号
ui->receiveMessage_te->setTextColor(QColor(0,255,0)); ui->receiveMessage_te->setFont(QFont("Timers",50,QFont::Bold));
if(receiveHexState==1)
{ qDebug()<<"输出16进制字符串str:";
str+=buf.toHex();
qDebug()<<buf.toHex();
ui->receiveMessage_te->append(str);
}
else {
str+=buf;
qDebug()<<"输出字符串str:";
ui->receiveMessage_te->append(str);
// qDebug()<<str;
}
}
str.clear();
receiveHexString.clear();
buf.clear();
}
//清除发送区数据QVBoxLayout receiveVBL
void MainWindow::on_clearSend_btn_clicked()
{
this->ui->sendMessage_te->clear();
}
//执行清除接收区数据
void MainWindow::on_clrearReceive_btn_clicked()
{
this->ui->receiveMessage_te->clear();
}
void MainWindow::on_receiveToHex_ceb_stateChanged(int arg1)
{
qDebug()<<arg1;
if(arg1==2)
{
receiveHexState=1;
}
else
{
receiveHexState=0;
}
}
void MainWindow::on_sendToHex_ceb_stateChanged(int arg1)
{
qDebug()<<arg1;
if(arg1==2)
{
sendHexState=1;
}
else
{
sendHexState=0;
}
}
//进行保存接受的数据
void MainWindow::on_saveReceiveMessage_btn_clicked()
{
QString saveString =this->ui->receiveMessage_te->toPlainText();
//进行文件保存
qDebug() << "进行文件保存";
qDebug() << saveString;
//获取系统当前目录
QString curPath=QDir::currentPath();
qDebug() << curPath;
QString dlgTitle="另存为一个文件"; //对话框标题
QString filter="h文件(*.h);;c++文件(*.cpp);;文本文件(*.txt);;所有文件(*.*)"; //文件过滤器
QString aFileName=QFileDialog::getSaveFileName(this,dlgTitle,curPath,filter);
//输出要保存的文件名
qDebug() << "保存文件为:";
qDebug() << aFileName;
if (aFileName.isEmpty())
return;
QFile aFile(aFileName);
if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text))
return ;
QByteArray strBytes=saveString.toUtf8();//转换为字节数组 aFile.write(strBytes,strBytes.length()); //写入文件
aFile.close();
//ui->tabWidget->setCurrentIndex(0);
}
5、mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>837</width>
<height>685</height>
</rect>
</property>
<property name="font">
<font> <weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="windowTitle">
<string>通用通讯软件V1.0 如有需要联系1527090149@qq.com</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="clrearReceive_btn">
<property name="geometry">
<rect>
<x>20</x>
<y>260</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>清空接收</string>
</property>
</widget>
<widget class="QTextEdit" name="sendMessage_te">
<property name="geometry">
<rect>
<x>20</x>
<y>370</y>
<width>600</width>
<height>150</height>
</rect>
</property>
</widget>
<widget class="QTextEdit" name="receiveMessage_te">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>600</width>
<height>200</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="receive_lb">
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>121</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>接收数据</string>
</property>
</widget>
<widget class="QLabel" name="send_lb">
<property name="geometry">
<rect>
<x>20</x>
<y>330</y>
<width>121</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>发送数据</string>
</property>
</widget>
<widget class="QPushButton" name="clearSend_btn">
<property name="geometry">
<rect>
<x>30</x>
<y>530</y>
<width>100</width>
<height>50</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>清空发送</string>
</property>
</widget>
<widget class="QCheckBox" name="receiveToHex_ceb">
<property name="geometry">
<rect>
<x>510</x>
<y>270</y>
<width>111</width>
<height>50</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>16进制显示</string>
</property>
</widget>
<widget class="QCheckBox" name="sendToHex_ceb">
<property name="geometry">
<rect>
<x>510</x>
<y>530</y>
<width>121</width>
<height>50</height>
</rect>
</property>
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>16进制发送</string>
</property> </widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>660</x>
<y>70</y>
<width>156</width>
<height>136</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>串口号:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comSelect_cbb">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<item>
<property name="text">
<string>COM1</string>
</property>
</item>
<item>
<property name="text">
<string>COM2</string>
</property>
</item>
<item>
<property name="text">
<string>COM3</string>
</property>
</item>
<item>
<property name="text">
<string>COM4</string>
</property>
</item>
<item>
<property name="text">
<string>COM5</string>
</property>
</item>
<item>
<property name="text">
<string>COM6</string>
</property>
</item>
<item>
<property name="text">
<string>COM7</string>
</property>
</item>
<item>
<property name="text">
<string>COM8</string>
</property>
</item>
<item>
<property name="text">
<string>COM9</string>
</property>
</item>
<item>
<property name="text">
<string>COM10</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>波特率:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="baudSelect_cbb">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>1200</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>数据位:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_3">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>校验位;</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_4">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<item>
<property name="text">
<string>0</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>停止位:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBox_5">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>650</x>
<y>377</y>
<width>78</width>
<height>124</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="openSerial_btn">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>打开串口</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="closeSerial_btn">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>关闭串口</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="sendMessage_btn">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>发送数据</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="saveReceiveMessage_btn">
<property name="font">
<font>
<family>AcadEref</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>保存数据</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>837</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
以上为该程序的所有代码,如有问题,请留言,后面会持续更新请关注!