Qt 线程串口

news2024/9/21 4:40:53

文章目录

  • ui设置
  • 创建线程函数
  • 初始串口
  • run函数接收发送数据
    • 读取数据
    • 处理读取的数据
    • 写入数据
    • 写入启动的命令
  • 主线程

在这里插入图片描述

ui设置

在这里插入图片描述

创建线程函数

#include <QObject>
#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>

class SerialPort : public QThread
{
    Q_OBJECT
public:
    SerialPort();
    ~SerialPort();

public:
    void InitPort(QString PortName);
    void wirteData();//写入数据
    void ProcessReceivedData(QByteArray);//处理数据
    quint8  CalculateChecksum(const QByteArray& data);//计算校验和
signals:
    void SendData(float m_fVol[10]);//发送数据

protected:
    void run();

public slots:
    void readData();
    void handleBytesWritten(quint64 bytes);

public:
    QSerialPort* port;
    QStringList serialPortNameList;//串口列表
    float m_fVol[10];//电压
    QByteArray m_receivedBuffer[4096];
    QByteArray receivedData;//接收到的数据
};

初始串口

void SerialPort::InitPort(QString PortName)
{
    // 查询所有串口设备
//    QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();

//    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
//    {
//        serialPortNameList << info.portName();
//        qDebug()<<"serialPortName: "<<info.portName();
//    }


    //qDebug()<<PortName;
    port->setPortName(PortName);
    port->setBaudRate(19200, QSerialPort::AllDirections);//波特率
    port->setDataBits(QSerialPort::Data8);             // 数据位为8位
    port->setFlowControl(QSerialPort::NoFlowControl);  // 无流控制
    port->setParity(QSerialPort::NoParity);            // 无校验位
    port->setStopBits(QSerialPort::OneStop);           // 一位停止位

    if (port->open(QIODevice::ReadWrite))
    {
        qDebug() << "Port have been opened";
        wirteData();
    }
    else
    {
        qDebug() << "open it failed";

        return;
    }
}

run函数接收发送数据

void SerialPort::run()
{
    connect(port, &QSerialPort::bytesWritten, this, &SerialPort::handleBytesWritten);//向串口写数据
    connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
    exec();
}

读取数据

void SerialPort::readData()
{
    if (port->bytesAvailable() > 0)
        {
            qint64 nReadSize = 4096;
            if(port->isOpen())
            {
                QByteArray receivedData = port->read(nReadSize);

                //qDebug()<<receivedData.size();
                if (receivedData.size() >= 26)
                {
                    ProcessReceivedData(receivedData); // 处理接收到的数据
                }
            }
        }
}

处理读取的数据

void SerialPort::ProcessReceivedData(QByteArray receivedData)
{
    //qDebug()<<receivedData;
    //qDebug()<<receivedData.size();

    if(receivedData.size() >= 26)
    {
        if (receivedData.at(0) == 'U' && receivedData.at(receivedData.length() - 1) == '\xAA')
        {
            // 检验校验和
            //qDebug()<<receivedData;
            QByteArray dataContent = receivedData.mid(1, 23);

            quint8 receivedChecksum = static_cast<quint8>(receivedData.at(24)); // 获取接收到的校验和
            quint8 calculatedChecksum = CalculateChecksum(dataContent); // 计算校验和

            if(receivedChecksum ==calculatedChecksum )//数据正确
            {
                quint16 wT;
                for (int j = 0; j < 10; ++j)
                {
                    wT = static_cast<quint8>(receivedData[j*2+2]);
                    wT <<= 8;
                    wT += static_cast<quint8>(receivedData[j*2+1]);
                    m_fVol[j] = wT * 5000.0f / 1024;
                    emit SendData(m_fVol);
                }

            }


        }
        else
        {
            receivedData.remove(0, 1);
        }

    }

}

quint8 SerialPort::CalculateChecksum(const QByteArray &data)
{
    quint8 checksum = 0;

    for (int i = 0; i < data.size(); ++i)
    {
        checksum += static_cast<quint8>(data.at(i));
    }

    return checksum;
}

写入数据

void SerialPort::handleBytesWritten(quint64 bytes)
{
    if (bytes > 0)
    {
        // 数据写入成功
        //qDebug()<<bytes;
        connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
    } else {
        // 数据写入失败
        wirteData();//再次写入
    }
}

写入启动的命令

void SerialPort::wirteData()
{
    if (port->isOpen())
    {
        QByteArray data;
        data.append(char(0x55)); // 添加数据 0x55 到数组
        data.append(char(0x01)); // 添加数据 0x01 到数组
        data.append(char(0x01)); // 添加数据 0x01 到数组
        data.append(char(0x00)); // 添加数据 0x00 到数组
        data.append(char(0x00)); // 添加数据 0x00 到数组
        data.append(char(0x00)); // 添加数据 0x00 到数组
        data.append(char(0x02)); // 添加数据 0x02 到数组
        data.append(char(0xAA)); // 添加数据 0xAA 到数组
        //qDebug()<<char(0x55);
        port->clear(QSerialPort::Output); // 清除输出缓冲区
        port->write(data);                // 写入数据到串口
    }
}

主线程

#include <QWidget>
#include "serialport.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

public slots:
    void ReadData(float m_fVol[10]);


public:
    SerialPort* m_Port;

private slots:
    void on_pushButton_clicked();
};
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_Port =new SerialPort();
    ui->comboBox->addItem("COM1");
    ui->comboBox->addItem("COM2");
    ui->comboBox->addItem("COM3");
    ui->comboBox->addItem("COM4");
    ui->comboBox->addItem("COM5");
    ui->comboBox->addItem("COM6");
    ui->comboBox->addItem("COM7");
    ui->comboBox->addItem("COM8");


}

Widget::~Widget()
{
    delete ui;
}

void Widget::ReadData(float m_fVol[10])
{

    QTextCursor tc = ui->textBrowser->textCursor();
    tc.movePosition(QTextCursor::End);
    //qDebug()<<m_fovl;
    for(int i=0;i<10;i++)
    {
         tc.insertText(QString::number(m_fVol[i])+"mv\n");
         tc.insertText("\n");
    }

    tc.insertText("----------\n");


    ui->textBrowser->moveCursor(QTextCursor::End);
}




void Widget::on_pushButton_clicked()
{
    if(ui->pushButton->text() == "连接")
    {
        m_Port->InitPort(ui->comboBox->currentText());
        connect(m_Port,&SerialPort::SendData,this,&Widget::ReadData);
        m_Port->start();
        ui->pushButton->setText("断开连接");
    }
    else {
        m_Port->port->close();
        disconnect(m_Port, &SerialPort::SendData, this, &Widget::ReadData); // 断开连接
        ui->pushButton->setText("连接");
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1202766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电容隔离型±10V输入度隔离放大器:ISOC 124P

度模拟电压信号隔离器。50KHz (-3dB)高带宽与ISO 124P隔离器Pin-Pin兼容。ISOC 124P模拟电压信号隔离放大器是一种采用电容耦合隔离的混合集成电路&#xff0c;该放大器采用了全新的调制-解调电容耦合隔离技术。模块中信号以数字的形式通过电容隔离层进行传输&#xff0c;通过数…

【python自动化】Playwright基础教程(八)鼠标操作

【python自动化】Playwright基础教程(八)鼠标操作 本文目录 文章目录 【python自动化】Playwright基础教程(八)鼠标操作playwright系列回顾前文代码click模拟鼠标点击dblclick模拟鼠标双击down模拟鼠标按下move模拟鼠标移动up模拟鼠标释放wheel模拟鼠标滚动鼠标长按常用实战引…

Day02_《MySQL索引与性能优化》

文章目录 一、SQL执行顺序二、索引简介1、关于索引2、索引的类型Btree 索引Btree 索引 三、Explain简介四、Explain 详解1、id2、select_type3、table4、type5、possible_keys6、key7、key_len8、ref9、rows10、Extra11、小案例 五、索引优化1、单表索引优化2、两表索引优化3、…

react使用wx-open-launch-weapp的方法

index.html中加载 <script src"https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> ios浏览器中,建议直接在app.js中触发 wx.config,其中openTagList写上wx-open-launch-weapp 因为微信需要根据网址计算签名,iosreact中会以根目录为有效网址 …

淘宝开放平台订单接口免申请审核接入规则

大家都知道&#xff0c;想要实现自动化批量获取淘宝的商品订单数据&#xff0c;离不开淘宝开放平台API接口。想要获取API调用权限&#xff0c;需要经过淘宝开放平台的严苛审核流程。并且&#xff0c;现在平台基本不开放新的应用权限了。像很多做ERP的公司&#xff0c;他们的客户…

用Java开发一个扫雷游戏

以下是用Java开发一个扫雷游戏的基本步骤&#xff1a; 创建一个窗口和画布&#xff0c;用来显示游戏界面。 创建一个游戏逻辑类&#xff0c;包含一些基本的操作&#xff0c;如生成地雷、计算周围地雷数量、打开方格等。 在画布上绘制游戏界面&#xff0c;包括格子、数字、地雷…

华为ensp:边缘端口并启动BUDU保护

如上图前提是三个交换机都做了rstp&#xff0c;则在边缘的地方做 边缘端口并启动BUDU保护&#xff0c;也就是我用绿色圈出来的地方 边缘1 进入交换机的系统视图 interface e0/0/3 进入接口 stp edged-port enable quit 再退回系统视图 stp bpdu-protection 这样就可以了…

前端工具nvm实现node自由

node的自由之路 前言 大家使用vue框架开发的朋友可能会遇到首次运行公司项目环境的时候&#xff0c;会出现使用npm install命令安装依赖包的时候出现各种各样的问题&#xff0c;其中很重要的一个错误原因就是因为你的nodejs版本和当时搭建环境的版本不一致造成的。今天就来给…

C语言精华题目锦集1

第一题 test.c文件中包括如下语句&#xff0c;文件中定义的四个变量中&#xff0c;是指针类型的是&#xff08;&#xff09;【多选】 #define INT_PTR int* typedef int* intptr; INT_PRT a,b; int_ptr c,d;A:a  B:b  C:c  D:d #define是宏定义&#xff0c;此时在程序中IN…

软考网络工程师知识点总结(四)

目录 61、FTP文件传输服务 62、DHCP动态主机配置协议 63、电子邮件服务 64、各种新技术相关概念及功能的考查 65、Windows的ipconfig命令 66、Windows的其它命令及说明 67、Linux系统关机和重启命令 68、Linux系统文件属性命令 69、SNMP协议版本 70、SNMP协议的报文类…

移远EC600U-CN开发板 day04

控件探索-滑杆&#xff08;lv.slider&#xff09; 1. 显示一个简单的滑杆 def slider_event_cb(evt): slider evt.get_target()# 修改label的值label.set_text(str(slider.get_value()))slider lv.slider(scr) #创建滑杆组件 slider.set_width(200) #设置滑杆宽…

OpenCV 实现透视变换

一&#xff1a;OpenCV透视变换的概念 仿射变换(affine transform)与透视变换(perspective transform)在图像还原、图像局部变化处理方面有重要意义。通常&#xff0c;在2D平面中&#xff0c;仿射变换的应用较多&#xff0c;而在3D平面中&#xff0c;透视变换又有了自己的一席之…

华视电子驱动安装

1、安装驱动 下载地址&#xff1a;http://ws.it0355.com/a/202101/07/a27013.htm 双击exe文件安装驱动&#xff1a; 检查驱动运行正常&#xff1a; http://www.winwin7.com/soft/xtbd-12727.html vc库安装

https:/myproject.git did not send all necessary objects

事情是由于在git push 的时候&#xff0c;电脑突然蓝屏了&#xff0c;再打开电脑的时候&#xff0c;git pull git push都失效了&#xff0c; 粗暴的解决方式是重新在拉取代码&#xff0c;可以暂时解决&#xff0c;但是考虑到可能以后还会遇到这个问题&#xff0c;所以在不紧急…

取暖器/暖风机上架 亚马逊美国站UL1278测试标准要求

美国是一个对安全要求非常严格的国家&#xff0c;美国本土的所有电子产品生产企业早在很多年前就要求有相关检测。而随着亚马逊在全球商业的战略地位不断提高&#xff0c;境外的电子设备通过亚马逊不断涌入美国市场。“为保证消费者得安全&#xff0c;亚马逊始终强调带电得产品…

Perl爬虫程序的框架

Perl爬虫程序的框架&#xff0c;这个框架可以用来爬取任何网页的内容。 perl #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; # 创建LWP::UserAgent对象 my $ua LWP::UserAgent->new; # 设置代理信息 $ua->proxy(http, ); …

【python自动化】Playwright基础教程(九)-悬浮元素定位自定义ID定位组合定位断言

【python自动化】Playwright基础教程&#xff08;九&#xff09;-悬浮元素定位&自定义ID定位&组合定位&断言 本文目录 文章目录 【python自动化】Playwright基础教程&#xff08;九&#xff09;-悬浮元素定位&自定义ID定位&组合定位&断言playwright系…

Egg.js 中 Service 的使用

Service 服务 Service是用来编写和数据库直接交互的业务逻辑代码。Service就是在复杂业务场景下用于做业务逻辑封装的一个抽象层。 简单来说&#xff0c;就是把业务逻辑代码进一步细化和分类&#xff0c;所以和数据库交互的代码都放到Service中。这样作有三个明显的好处。 保…

学会这10个Fluent仿真优化技巧,效率蹭蹭蹭

ANSYS Fluent 是计算流体动力学 (CFD) 仿真的强大工具&#xff0c;使工程师和科学家能够分析和预测各种应用中的流体行为。然而&#xff0c;运行模拟可能需要大量计算&#xff0c;因此优化设置对于在最短的时间内获得最准确的结果非常重要。 Fluent对电脑配置要求高&#xff1f…

server2008、2016远程桌面授权的激活方法

远程桌面服务安装好之后使用的是120天临时授权&#xff0c;所以会跳出以下提示&#xff0c;我们介绍远程桌面授权的激活。 现在我们使用命令 mstsc /admin 强制登录服务器 需要在“远程桌面服务”--安装“远程桌面授权”--默认安装 “计算机”单击右键“管理”--“角色” 默认…