环境说明
Qt版本:5.12 Mingw32操作系统:win10
实现的功能
与单片机之间进行串口通信,其中串口通信的程序放在子线程。
直接上代码
QT开发交流+赀料君羊:661714027
QT开发交流+赀料君羊:661714027
头文件
//myserial.h
#ifndef MYSERIAL_H
#define MYSERIAL_H
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QString>
#include <QThread>
#include <QDebug>
class mySerial : public QThread
{
Q_OBJECT
public:
mySerial();
~mySerial();
void SerialConnect();
void mySerialDisconnect();
void run();
void setcmbPortName(QString portName);
void setcmbBaudRate(QString baudRate);
void setcmbDataBits(int DataBits);
void setcmbParity(int Parity);
void setcmbFlowControl(int FlowControl);
void setcmbStopBits(int StopBits);
QByteArray readAll();
void write(QByteArray sendData_2);
public slots:
void readComDataSlot();
signals:
void message(const QByteArray);
void isNotConnected();
protected:
void handleSerialError(QSerialPort::SerialPortError error);
private:
QSerialPort *my_serialport;
QString cmbPortName;
QString cmbBaudRate;
int cmbDataBits;
int cmbParity;
int cmbFlowControl;
int cmbStopBits;
bool disconnectbit=false;
};
#endif // MYSERIAL_H
CPP文件
//myserial.cpp
#include “myserial.h”
mySerial::mySerial()
{
my_serialport=new QSerialPort();
}
mySerial::~mySerial()
{
delete my_serialport;
}
void mySerial::run()
{
while(1)
{
if(disconnectbit==true)
{
break;
}
}
}
void mySerial::SerialConnect()
{
my_serialport->setPortName(cmbPortName);
//以读写方式打开串口
if(my_serialport->open(QIODevice::ReadWrite))
{
//设置波特率
my_serialport->setBaudRate(cmbBaudRate.toInt());
//设置数据位
switch(cmbDataBits)
{
case 0:my_serialport->setDataBits(QSerialPort::Data5);break;
case 1:my_serialport->setDataBits(QSerialPort::Data6);break;
case 2:my_serialport->setDataBits(QSerialPort::Data7);break;
case 3:my_serialport->setDataBits(QSerialPort::Data8);break;
default:break;
}
switch(cmbParity)
{
case 0:my_serialport->setParity(QSerialPort::NoParity);break;
case 1:my_serialport->setParity(QSerialPort::OddParity);break;
case 2:my_serialport->setParity(QSerialPort::EvenParity);break;
default:break;
}
//设置流控制
switch (cmbFlowControl) {
case 0:my_serialport->setFlowControl(QSerialPort::NoFlowControl);break;
case 1:my_serialport->setFlowControl(QSerialPort::FlowControl());
}
//设置停止位
switch(cmbStopBits)
{
case 0:my_serialport->setStopBits(QSerialPort::OneStop);break;
case 1:my_serialport->setStopBits(QSerialPort::OneAndHalfStop);break;
case 2:my_serialport->setStopBits(QSerialPort::TwoStop);break;
}
//每秒读一次
connect(my_serialport, SIGNAL(readyRead()), this, SLOT(readComDataSlot()));
connect(my_serialport, static_cast<void (QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error), this, &mySerial::handleSerialError);
}
else
{
my_serialport->close();
}
}
void mySerial::handleSerialError(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError) {
mySerialDisconnect();
}
emit isNotConnected();
}
void mySerial::readComDataSlot()
{
//读取串口数据
QByteArray readComData = my_serialport->readAll();
//qDebug()<<readComData<<endl;
//将读到的数据显示到数据接收区的te中
if(!readComData.isNull())
{
message(readComData);
}
//清除缓冲区
readComData.clear();
}
QByteArray mySerial::readAll()
{
QByteArray readComData = my_serialport->readAll();
return readComData;
}
void mySerial::write(QByteArray sendData_2)
{
my_serialport->write(sendData_2);
}
void mySerial::mySerialDisconnect()
{
my_serialport->close();
}
void mySerial::setcmbPortName(QString PortName)
{
cmbPortName=PortName;
}
void mySerial::setcmbBaudRate(QString BaudRate)
{
cmbBaudRate=BaudRate;
}
void mySerial::setcmbDataBits(int DataBits)
{
cmbDataBits=DataBits;
}
void mySerial::setcmbParity(int Parity)
{
cmbParity=Parity;
}
void mySerial::setcmbFlowControl(int FlowControl)
{
cmbFlowControl=FlowControl;
}
void mySerial::setcmbStopBits(int StopBits)
{
cmbStopBits=StopBits;
}
//wigth.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include “myserial.h”
#include <QTimer>
#include <QTime>
#include <QDebug>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void handleSerialError();
void cmbPortNameRefresh();
void readComDataSlot(QByteArray message);
private slots:
void on_btnOpen_released();
void on_btnSend_released();
void on_clearRecive_released();
void on_clearSend_released();
void on_cbReceive_stateChanged(int arg1);
void on_cbSend_stateChanged(int arg1);
void on_teReceiveData_textChanged();
void on_teReceiveDataHex_textChanged();
void on_teSendData_textChanged();
void on_teSendDataHex_textChanged();
private:
Ui::Widget *ui;
QTimer *timer;
mySerial *my_serialport;
bool state=false;
QString beforeport;
bool HexState=false;
bool TimeState=false;
bool receiveStat=true;
bool sendStat=true;
bool SendStat=true;
void portRefresh();
QString ByteArrayToHexString(QByteArray data);
QString getCurrentTime();
void initPort();
QString deleteCharString0(QString sourceString, char chElemData);
};
#endif // WIDGET_H
//wigth.cpp
#include “widget.h”
#include “ui_widget.h”
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
initPort();
timer=new QTimer();
connect(timer,SIGNAL(timeout()),this,SLOT(cmbPortNameRefresh()));
my_serialport=new mySerial();
connect(my_serialport,SIGNAL(message(QByteArray)),this,SLOT(readComDataSlot(QByteArray)));
connect(my_serialport,SIGNAL(isNotConnected()), this, SLOT(handleSerialError()));
timer->start(1000);
ui->teReceiveDataHex->setVisible(false);
ui->teSendDataHex->setVisible(false);
}
void Widget::initPort()
{
portRefresh();
QStringList baudList;//波特率
QStringList parityList;//校验位
QStringList dataBitsList;//数据位
QStringList stopBitsList;//停止位
QStringList flowControlList;
baudList<<”256000”<<”128000”<<”115200”<<”76800”<<”57600”<<”56000”<<”38400”
<<”19200”<<”14400”<<”9600”<<”4800”<<”2400”<<”1800”
<<”1200”<<”600”<<”300”<<”200”<<”134”
<<”100”<<”75”<<”50”;
ui->cmbBaudRate->addItems(baudList);
ui->cmbBaudRate->setCurrentIndex(9);
parityList<<”无”<<”奇”<<”偶”;
ui->cmbParity->addItems(parityList);
ui->cmbParity->setCurrentIndex(0);
dataBitsList<<”5”<<”6”<<”7”<<”8”;
ui->cmbDataBits->addItems(dataBitsList);
ui->cmbDataBits->setCurrentIndex(3);
stopBitsList<<”1”;
stopBitsList<<”1.5”;
stopBitsList<<”2”;
ui->cmbStopBits->addItems(stopBitsList);
ui->cmbStopBits->setCurrentIndex(0);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleSerialError()
{
ui->btnOpen->setText(“打开串口”);
ui->cmbPortName->setEnabled(true);
ui->cmbBaudRate->setEnabled(true);
ui->cmbParity->setEnabled(true);
ui->cmbDataBits->setEnabled(true);
ui->cmbStopBits->setEnabled(true);
state=false;
}
void Widget::cmbPortNameRefresh()
{
portRefresh();
}
void Widget::portRefresh()
{
beforeport=ui->cmbPortName->currentText();
ui->cmbPortName->clear();
//读取串口信息
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
//将串口号添加到cmb
ui->cmbPortName->addItem(info.portName());
for ( int i = 0 ; i < ui->cmbPortName->count(); i ++ )
{
if(ui->cmbPortName->itemText(i)==beforeport)
{
ui->cmbPortName->setCurrentIndex(i);
}
}
}
}
QString Widget::ByteArrayToHexString(QByteArray data){
QString ret(data.toHex().toUpper());
int len = ret.length()/2;
for(int i=1;i<len;i++)
{
ret.insert(2*i+i-1,” “);
}
return ret;
}
void Widget::readComDataSlot(QByteArray message)
{
//读取串口数据
QByteArray readComData = message;
QString num=message;
num=deleteCharString0(num,0x0a);
// qDebug()<<num<<endl;
//if(HexState==true)
if(false)
{
QString date= ByteArrayToHexString(readComData);
readComData=date.toLatin1();
}
//将读到的数据显示到数据接收区的te中
if(!readComData.isNull())
{
ui->teReceiveData->append(readComData);
if(TimeState)
{
QString time=getCurrentTime();
ui->teReceiveData->append(time);
}
}
//清除缓冲区
readComData.clear();
}
QString Widget::getCurrentTime()
{
QTime current_time =QTime::currentTime();
int hour = current_time.hour();//当前的小时
int minute = current_time.minute();//当前的分
int second = current_time.second();//当前的秒
int msec = current_time.msec();//当前的毫秒
QString time=QString::number(hour,10)+”:”+QString::number(minute,10)+”:”+QString::number(second,10)+”:”+QString::number(msec,10);
return time;
}
void Widget::on_btnOpen_released()
{
timer->stop();
if(state==false)
{
//设置串口号
if(!ui->cmbPortName->currentText().isNull())
{
my_serialport->setcmbPortName(ui->cmbPortName->currentText());
my_serialport->setcmbBaudRate(ui->cmbBaudRate->currentText());
my_serialport->setcmbDataBits(ui->cmbDataBits->currentIndex());
my_serialport->setcmbParity(ui->cmbParity->currentIndex());
my_serialport->setcmbFlowControl(0);
my_serialport->setcmbStopBits(ui->cmbStopBits->currentIndex());
my_serialport->SerialConnect();
//每秒读一次
ui->cmbPortName->setEnabled(false);
ui->cmbBaudRate->setEnabled(false);
ui->cmbParity->setEnabled(false);
ui->cmbDataBits->setEnabled(false);
ui->cmbStopBits->setEnabled(false);
ui->btnOpen->setText(“关闭串口”);
state=true;
//QMessageBox::about(NULL, “Sign”, “Serial is opened!”);
}
}
else
{
state=false;
ui->btnOpen->setText(“打开串口”);
ui->cmbPortName->setEnabled(true);
ui->cmbBaudRate->setEnabled(true);
ui->cmbParity->setEnabled(true);
ui->cmbDataBits->setEnabled(true);
ui->cmbStopBits->setEnabled(true);
my_serialport->mySerialDisconnect();
}
timer->start(1000);
}
void Widget::on_btnSend_released()
{
//获取发送区的数据
QString sendData = ui->teSendData->toPlainText();
QByteArray sendData_2 = sendData.toLatin1();
//写入缓冲区
my_serialport->write(sendData_2);
}
void Widget::on_clearRecive_released()
{
ui->teReceiveData->clear();
}
void Widget::on_clearSend_released()
{
ui->teSendData->clear();
}
void Widget::on_cbReceive_stateChanged(int arg1)
{
if(ui->cbReceive->isChecked())
{
ui->teReceiveData->setVisible(false);
ui->teReceiveDataHex->setVisible(true);
receiveStat=false;
}
else {
ui->teReceiveDataHex->setVisible(false);
ui->teReceiveData->setVisible(true);
receiveStat=true;
}
qDebug()<<receiveStat<<endl;
}
void Widget::on_cbSend_stateChanged(int arg1)
{
if(ui->cbSend->isChecked())
{
ui->teSendData->setVisible(false);
ui->teSendDataHex->setVisible(true);
sendStat=false;
}
else {
ui->teSendDataHex->setVisible(false);
ui->teSendData->setVisible(true);
sendStat=true;
}
}
void Widget::on_teReceiveData_textChanged()
{
if(receiveStat==true)
{
QString string1= ui->teReceiveData->toPlainText();
ui->teReceiveDataHex->clear();
ui->teReceiveDataHex->setText(ByteArrayToHexString(string1.toUtf8()));
}
}
QString Widget::deleteCharString0(QString sourceString, char chElemData) {
QString resultString = “”;
for (int i = 0; i < sourceString.length(); i++) {
if (sourceString.at(i)!= chElemData) {
resultString += sourceString.at(i);
}
}
return resultString;
}
void Widget::on_teReceiveDataHex_textChanged()
{
if(receiveStat==false)
{
QString string1= ui->teReceiveDataHex->toPlainText();
string1=deleteCharString0(string1,’ ‘);
QString string2=””;
for(int i=0;i<string1.length();i++,i++)
{
char num=new char[2];
QString num2=””;
if(i<string1.length()-1)
{
num[0]=string1.at(i).toLatin1();
num[1]=string1.at(i+1).toLatin1();
num2=QString::fromUtf8(num);
}
else {
num[0]=’0’;
num[1]=string1.at(i).toLatin1();
num2=QString::fromUtf8(num);
}
char c=(num[0]-0x30)16+num[1]-0x30;
string2.append(c);
}
ui->teReceiveData->clear();
ui->teReceiveData->setText(string2);
}
}
void Widget::on_teSendData_textChanged()
{
if(sendStat==true)
{
QString string1= ui->teSendData->toPlainText();
ui->teSendDataHex->clear();
ui->teSendDataHex->setText(ByteArrayToHexString(string1.toUtf8()));
}
}
void Widget::on_teSendDataHex_textChanged()
{
if(sendStat==false)
{
QString string1= ui->teSendDataHex->toPlainText();
string1=deleteCharString0(string1,’ ‘);
QString string2=””;
for(int i=0;i<string1.length();i++,i++)
{
char num=new char[2];
QString num2=””;
if(i<string1.length()-1)
{
num[0]=string1.at(i).toLatin1();
num[1]=string1.at(i+1).toLatin1();
num2=QString::fromUtf8(num);
}
else {
num[0]=’0’;
num[1]=string1.at(i).toLatin1();
num2=QString::fromUtf8(num);
}
char c=(num[0]-0x30)16+num[1]-0x30;
string2.append(c);
}
ui->teSendData->clear();
ui->teSendData->setText(string2);
}
}
界面展示
左右两边的控件均为QTableView。
原文作者:异想天开的余瑞银
原文地址:https://blog.csdn.net/qq_34790664/article/details/115215451