QT开发中文网

Qt串口通信


环境说明

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

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://qt.0voice.com/?id=1777

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?