Qt:采用第三方串口类CSerialPort V4.0.3开发的串口助手,支持高波特率

2 篇文章 1 订阅
2 篇文章 0 订阅

首先感谢itas109大佬的开源代码,用起来真的简单方便,且经过多年修改完善代码整体框架比较健全,很多大公司都在使用这个串口类。

初次使用这个串口类是在MFC下开发串口通讯时使用的(代码链接:使用CSerialPort开源类在MFC下开发的串口助手),当时就感觉特别的简单方便,之后因为项目需要就在Qt下开始使用了,刚开始使用了Qt自带的串口类,但是感觉操作繁琐,且不支持高波特率,后来又还了Qt的第三方串口类qextserialport类,但是因为缺乏维护且问题较多,所以最后还是找了itas109大佬的开源串口类,结果显而易见,在Qt环境下的使用还是一如既往的方便简单,且本人实测,921600波特率下,20ms周期发送接收数据稳定!

重点来了:itas109大佬博客:http://blog.csdn.net/itas109
QQ群,平时遇到的问题或者串口使用想到的新需求都可以在群里提:129518033
Git:https://github.com/itas109/CSerialPort里边有最新版本的发布以及以往个版本的更新说明;
环境:QT5.6.3
效果图:

这是软件界面,有定时发送,十六进制发送接收以及字符发生接收的功能
下面时代码的大体结构:
大体结构

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include "SerialPort.h"

using namespace std;
using namespace itas109;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow, public has_slots<>
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    //转16进制
    QByteArray QString2Hex(QString str);
    char ConvertHexChar(char ch);
    QTimer *m_time;

private slots:
    void OnReceive();

    void OnUpdateReceive(QString str);

    void on_pushButtonOpen_clicked();

    void on_pushButtonSend_clicked();

    void on_pushButtonClear_clicked();

    void on_checkBoxSync_stateChanged(int arg1);

    void on_pushButtonReadSync_clicked();

    void on_checkBoxSync_clicked(bool checked);

    void time_send();

signals:
    void emitUpdateReceive(QString str);

private:
    Ui::MainWindow *ui;

    CSerialPort m_SerialPort;

    int tx;
    int rx;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "SerialPortInfo.h"
#include <QDebug>
#include <QScrollBar>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->spinBox->setMaximum(5000);
    ui->spinBox->setMinimum(5);
    connect(this,&MainWindow::emitUpdateReceive,this,&MainWindow::OnUpdateReceive,Qt::QueuedConnection);

    //hide pushButtonReadSync
    ui->pushButtonReadSync->hide();//隐藏这个控件

    //ui
    ui->pushButtonOpen->setText(tr("open"));
    rx = 0;
    tx = 0;
    setWindowTitle(this->windowTitle() + "串口助手" +QString::fromStdString(m_SerialPort.getVersion()));

    //自动获取端口
    vector<SerialPortInfo> portNameList = CSerialPortInfo::availablePortInfos();
    for (int i = 0; i < portNameList.size(); i++)
    {
        ui->comboBoxPortName->insertItem(i,QString::fromLocal8Bit(portNameList[i].portName.c_str()));
    }

    //初始化
    m_SerialPort.readReady.connect(this, &MainWindow::OnReceive);
    ui->comboBoxBaudrate->setCurrentText("115200");
    ui->comboBoxDataBit->setCurrentText("8");
    //qDebug() << QString::fromStdString(m_SerialPort.getVersion());
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::OnReceive()
{
    int iRet = -1;
    char * str = NULL;
    str = new char[512];
    iRet = m_SerialPort.readAllData(str);

    //qDebug() << "read length : " << iRet;
    if(iRet != -1)
    {
        // TODO: 中文需要由两个字符拼接,否则显示为空""
        QString m_str = QString::fromLocal8Bit(str,iRet);
        //qDebug() << "receive : " << m_str;
        emit emitUpdateReceive(m_str);//发出信号
	}
    else
    {

    }
    delete str;
    str = NULL;
}
void MainWindow::OnUpdateReceive(QString str)//显示数据
{
    rx += str.length();
    ui->labelRXValue->setText(QString::number(rx));

    //追加文本
    if(ui->checkBox->checkState()==Qt::Checked)//十六进制显示
    {
        QByteArray temp=str.toLatin1();
        QString str3 = temp.toHex().data();//以十六进制显示
        QString strDis;
        for(int i = 0;i<str3.length();i+=2)//填加空格
        {
               QString st = str3.mid (i,2);
               strDis += st;
               strDis += " ";
        }
        ui->plainTextEditReceive->moveCursor (QTextCursor::End);
        ui->plainTextEditReceive->insertPlainText(strDis);
    }
    else
    {
        ui->plainTextEditReceive->moveCursor (QTextCursor::End);
        ui->plainTextEditReceive->insertPlainText(str);
    }
}
void MainWindow::on_pushButtonOpen_clicked()//打开串口
{
    if(ui->pushButtonOpen->text() == tr("open"))
    {
        if(ui->comboBoxPortName->count() > 0)//检测到端口
        {
            //初始化串口
            m_SerialPort.init(ui->comboBoxPortName->currentText().toStdString(),
                              ui->comboBoxBaudrate->currentText().toInt(),
                              itas109::Parity(ui->comboBoxParity->currentIndex()),
                              itas109::DataBits(ui->comboBoxDataBit->currentText().toInt()),
                              itas109::StopBits(ui->comboBoxStopBit->currentIndex()));

            //打开串口
            if(m_SerialPort.open())
            {
                ui->pushButtonOpen->setText(tr("close"));
            }
            else
            {
                QMessageBox::information(NULL,tr("information"),tr("open port error"));
                ui->pushButtonOpen->setText(tr("open"));
                //qDebug()<< m_SerialPort.getLastError();
            }
        }
        else
        {
            QMessageBox::information(NULL,tr("information"),tr("This Computer no avaiable port"));
            //qDebug()<< "This Computer no avaiable port";
        }
    }
    else
    {
        m_SerialPort.close();
        ui->pushButtonOpen->setText(tr("open"));
    }
}
void MainWindow::on_pushButtonSend_clicked()//发送数据
{
    if(m_SerialPort.isOpened())
    {
        if(ui->checkBox_3->checkState()==Qt::Checked)//定时发送
        {
            int timecount=ui->spinBox->value();//定时器发送的周期
            m_time=new QTimer(this);
            connect(m_time,&QTimer::timeout,this,&MainWindow::time_send);
            m_time->start(timecount);
        }
        else
        {
            if(ui->checkBox_2->checkState()==Qt::Checked)//十六进制发
            {
                QByteArray m_senddata=QString2Hex(ui->plainTextEditSend->toPlainText());
                const char *s = m_senddata.constData();
                //支持中文并获取正确的长度
                m_SerialPort.writeData(s,m_senddata.length());
                tx+=m_senddata.length();
                ui->labelTXValue->setText(QString::number(tx));
            }
            else
            {
                QString sendStr = ui->plainTextEditSend->toPlainText();

                QByteArray ba = sendStr.toLocal8Bit();
                const char *s = ba.constData();

                //支持中文并获取正确的长度
                m_SerialPort.writeData(s,ba.length());
                tx += sendStr.length();
                ui->labelTXValue->setText(QString::number(tx));
            }
        }
    }
    else
    {
        QMessageBox::information(NULL,tr("information"),tr("please open serial port first"));
        //qDebug() << tr("please open serial port first");
    }
}
void MainWindow::time_send()//定时发送
{
    if(ui->checkBox_3->checkState()==Qt::Checked)//定时发送
    {
        if(ui->checkBox_2->checkState()==Qt::Checked)//十六进制发
        {
            QByteArray m_senddata=QString2Hex(ui->plainTextEditSend->toPlainText());
            const char *s = m_senddata.constData();
            //支持中文并获取正确的长度
            m_SerialPort.writeData(s,m_senddata.length());
            tx+=m_senddata.length();
            ui->labelTXValue->setText(QString::number(tx));
        }
        else
        {
            QString sendStr = ui->plainTextEditSend->toPlainText();
            QByteArray ba = sendStr.toLocal8Bit();
            const char *s = ba.constData();
            //支持中文并获取正确的长度
            m_SerialPort.writeData(s,ba.length());
            tx += sendStr.length();
            ui->labelTXValue->setText(QString::number(tx));
        }
    }
    else
    {
        m_time->stop();
    }
}
QByteArray MainWindow::QString2Hex(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 = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}
char MainWindow::ConvertHexChar(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::on_pushButtonClear_clicked()//清空
{
    tx = 0;
    rx = 0;

    ui->labelTXValue->setText(QString::number(tx));
    ui->labelRXValue->setText(QString::number(rx));
}

void MainWindow::on_checkBoxSync_stateChanged(int arg1)//状态改变选择框
{
    if(arg1 == 0)
    {
        m_SerialPort.close();
    }
    else
    {
        m_SerialPort.close();
    }
}

void MainWindow::on_pushButtonReadSync_clicked()//SYNC按键
{
    OnReceive();
}

void MainWindow::on_checkBoxSync_clicked(bool checked)//选择框选择
{
    //AsynchronousOperate
    if(checked)
    {
        m_SerialPort.setOperateMode(itas109::SynchronousOperate);

        ui->pushButtonReadSync->show();
    }
    else
    {
        m_SerialPort.setOperateMode(itas109::AsynchronousOperate);

        ui->pushButtonReadSync->hide();
    }

}

基本上整个项目的代码都在这里了,图片里的源码部分大家可以在我文章开头处的Git链接出进行下载,再次感谢itas109
大佬的开源代码,非常实用,倾力推荐!

需要项目源码请点击此处
有问题联系:xvlei_far@163.com

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值