qt 串口通信

2023-11-02

qt串口通信:需要用到QSerialport类。
1、pro文件中添加QT += serialport。
2、获取当前有哪些串口设备(QSerialPortInfo::availablePorts()))。
3、设置要打开的串口(setPortName),然后打开(open)。
4、设置串口的参数,波特率,数据位,控制位,奇偶未和停止位(setBaudRate,setDataBits,setFlowControl,setParity,setStopBits)
5、写数据和读数据。

虚拟串口百度云分享:
链接: https://pan.baidu.com/s/1sE_lFneZaFo8mvIYW4JA8Q 提取码: m8cn
如果只是练习,可以使用虚拟串口工具创建两个虚拟串口com6和com7.在这里插入图片描述
串口调试助手百度云分享:
链接: https://pan.baidu.com/s/1W3dSIrqxFDNhxMeGKRCUzg 提取码: 3wwq
然后和三方的串口调试工具通信,一个打开com6,一个打开com7.
在这里插入图片描述
如果不用第三方串口调试助手,可以自己开两个程序,一个打开com6,一个打开com7.
在这里插入图片描述
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtWidgets>
#include <QSerialPort>
#include <QSerialPortInfo>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    void convertStringToHex(const QString &str, QByteArray &byteData);
    char convertCharToHex(char ch);
    ~Widget();

private slots:
    void slotLoadSerialPort();
    void slotOpenSerialPort();
    void slotReadData();
    void slotSend();
    void slotCloseSerialPort();
private:
    Ui::Widget *ui;
    QPushButton* m_loadportbtn;
    QPushButton* m_openSerialPortbtn;
    QPushButton* m_sendbtn;
    QPushButton* m_closeSerialPortbtn;
    QComboBox* m_serialportbox;
    QComboBox* m_baudratebox;
    QComboBox* m_databitbox;
    QComboBox* m_stopbitbox;
    QComboBox* m_paritybox;
    QComboBox* m_flowcontrolbox;
    QLabel* m_portlab;
    QLabel* m_Baudratelab;
    QLabel* m_DataBitlab;
    QLabel* m_FlowControllab;
    QLabel* m_StopBitlab;
    QLabel* m_Paritylab;
    QLabel* m_readlab;
    QLineEdit* m_sendedit;
    QTextEdit* m_readedit;

    QStringList m_flowcontrollist;
    QStringList m_paritylist;
    QStringList m_stopbitlist;
    QStringList m_databitlist;
    QStringList m_baudratelist;
    QSerialPort* m_serialPort;
};

#endif // WIDGET_H


#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    m_serialPort = nullptr;
    m_portlab = new QLabel("端口:",this);
    m_serialportbox = new QComboBox(this);
    m_loadportbtn = new QPushButton("加载端口",this);
    m_openSerialPortbtn = new QPushButton("打开串口",this);
    m_closeSerialPortbtn = new QPushButton("关闭串口",this);
    m_Baudratelab = new QLabel("数据位:",this);
    m_DataBitlab = new QLabel("数据位:",this);
    m_FlowControllab = new QLabel("控制流:",this);
    m_Paritylab = new QLabel("校验位:",this);
    m_StopBitlab = new QLabel("停止位:",this);
    m_baudratebox = new QComboBox(this);
    m_databitbox = new QComboBox(this);
    m_flowcontrolbox = new QComboBox(this);
    m_paritybox = new QComboBox(this);
    m_stopbitbox = new QComboBox(this);
    m_sendbtn = new QPushButton("发送",this);
    m_sendedit = new QLineEdit(this);
    m_readlab = new QLabel("接收:",this);
    m_readedit = new QTextEdit(this);

    QGridLayout* lay = new QGridLayout(this);
    lay->addWidget(m_loadportbtn,0,0,1,2);
    lay->addWidget(m_portlab,1,0,1,1);
    lay->addWidget(m_serialportbox,1,1,1,1);
    lay->addWidget(m_Baudratelab,2,0,1,1);
    lay->addWidget(m_baudratebox,2,1,1,1);
    lay->addWidget(m_DataBitlab,3,0,1,1);
    lay->addWidget(m_databitbox,3,1,1,1);
    lay->addWidget(m_FlowControllab,4,0,1,1);
    lay->addWidget(m_flowcontrolbox,4,1,1,1);
    lay->addWidget(m_Paritylab,5,0,1,1);
    lay->addWidget(m_paritybox,5,1,1,1);
    lay->addWidget(m_StopBitlab,6,0,1,1);
    lay->addWidget(m_stopbitbox,6,1,1,1);
    lay->addWidget(m_openSerialPortbtn,7,0,1,2);
    lay->addWidget(m_closeSerialPortbtn,8,0,1,2);
    lay->addWidget(m_sendedit,9,0,1,1);
    lay->addWidget(m_sendbtn,9,1,1,1);
    lay->addWidget(m_readlab,10,0,1,1);
    lay->addWidget(m_readedit,11,0,1,2);
    this->setLayout(lay);

    m_flowcontrollist<<"无"<<"硬控制"<<"软控制";
    m_paritylist<<"No"<<"Even"<<"Odd"<<"Space"<<"Mark";
    m_baudratelist<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"57600"<<"115200";
    m_databitlist<<"5"<<"6"<<"7"<<"8";
    m_stopbitlist<<"1"<<"2"<<"1.5";
    m_baudratebox->addItems(m_baudratelist);
    m_databitbox->addItems(m_databitlist);
    m_flowcontrolbox->addItems(m_flowcontrollist);
    m_paritybox->addItems(m_paritylist);
    m_stopbitbox->addItems(m_stopbitlist);

    connect(m_loadportbtn,SIGNAL(clicked()),this,SLOT(slotLoadSerialPort()));
    connect(m_openSerialPortbtn,SIGNAL(clicked()),this,SLOT(slotOpenSerialPort()));
    connect(m_closeSerialPortbtn,SIGNAL(clicked()),this,SLOT(slotCloseSerialPort()));
    connect(m_sendbtn,SIGNAL(clicked()),this,SLOT(slotSend()));
}

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

void Widget::slotLoadSerialPort()
{
    QStringList m_serialPortName;
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //获取有效的串口列表
    {
        m_serialPortName << info.portName();
        qWarning()<<"serialPortName:"<<info.portName();
    }
    m_serialportbox->clear();
    m_serialportbox->addItems(m_serialPortName);
}

void Widget::slotCloseSerialPort()
{
    if (m_serialPort)
        m_serialPort->close();
}

void Widget::slotOpenSerialPort()
{
    m_serialPort = new QSerialPort(this);

    if(m_serialPort->isOpen())
    {
        m_serialPort->clear();
        m_serialPort->close();
    }
    m_serialPort->setPortName(m_serialportbox->currentText());

    if (!m_serialPort->open(QIODevice::ReadWrite))
    {
        qWarning()<<"打开串口"<<m_serialportbox->currentText()<<"失败";
        return;
    }

    m_serialPort->setBaudRate(m_baudratebox->currentText().toInt());
    m_serialPort->setDataBits((QSerialPort::DataBits)(m_databitbox->currentIndex()+5));
    m_serialPort->setFlowControl((QSerialPort::FlowControl)m_flowcontrolbox->currentIndex());
    int parity = m_paritybox->currentIndex();
    if (parity > 0)
        parity++;
    m_serialPort->setParity((QSerialPort::Parity)parity);
    m_serialPort->setStopBits((QSerialPort::StopBits)(m_stopbitbox->currentIndex()+1));

    qWarning()<<"打开串口"<<m_serialportbox->currentText()<<"成功";

    connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(slotReadData()));
}

void Widget::slotReadData()
{
    QString data = m_serialPort->readAll();
    qWarning()<<"接收数据:"<<data;
    m_readedit->append("接收数据:"+data);
}

void Widget::slotSend()
{
    if (m_serialPort)
    {
        if (!m_serialPort->isOpen())
            qWarning()<<"请打开一个串口";

        QString info = m_sendedit->text();
        QByteArray sendBuf;
//        if (info.contains(" "))
//        {
//            info.replace(QString(" "),QString(""));//我这里是把空格去掉,根据你们定的协议来
//        }
//        convertStringToHex(info, sendBuf); //把QString 转换 为 hex
        qWarning()<<"发送数据:"<<info<<m_serialPort->baudRate()<<m_serialPort->dataBits()<<m_serialPort->flowControl()<<m_serialPort->parity()<<m_serialPort->stopBits();

        sendBuf = info.toLocal8Bit();
        m_serialPort->write(sendBuf);
    }
}

//Qstring 转为 16进制的函数
void Widget::convertStringToHex(const QString &str, QByteArray &byteData)
{
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    byteData.resize(len/2);
    char lstr,hstr;
    for(int i=0; i<len; )
    {
        //char lstr,
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = convertCharToHex(hstr);
        lowhexdata = convertCharToHex(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        byteData[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    byteData.resize(hexdatalen);
}

//另一个 函数 char 转为 16进制
char Widget::convertCharToHex(char ch)
{
    /*
            0x30等于十进制的48,48也是0的ASCII值,,
            1-9的ASCII值是49-57,,所以某一个值-0x30,,
            就是将字符0-9转换为0-9

            */
    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);
}


注意:如果是在UBuntu系统上,你会发现有点不一样,串口可能打不开。
解决方法如下:
如果是第一次在UBuntu上打开串口,串口名一般为ttyUSB0,需要给串口设置权限,否则是无法打开成功的。设置权限方法如下:
方法一:

sudo chmod 666 /dev/ttyUSB0

方法二:
添加配置

sudo vim /etc/udev/rules.d/20-usb-serial.rules

内容为

KERNEL=="ttyUSB*"  MODE="0666"

匹配内核以 ttyUSB 开头的驱动, 权限为 666
使配置生效

sudo service udev reload
sudo service udev restart

如果不想修改权限, 还有一种方法是当前用户加入 dialout 组(ttyUSB0 设备文件属于这个组), 加入这个组后就有权限了, 之后重启一下

sudo usermod -aG dialout jianghuixin

详情介绍

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qt 串口通信 的相关文章

  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

    我正在使用 c NET MVC2 并尝试创建一个 ajax 表单来调用删除数据库记录 RemoveRelation 的方法 删除记录的过程正在按预期进行 删除记录后 表单应调用一个 JavaScript 函数 从视觉效果中删除该记录 Rem

随机推荐

  • 机器学习——为什么逻辑斯特回归(logistic regression)是线性模型

    问 逻辑斯蒂回归是一种典型的线性回归模型 答 正确 逻辑斯蒂回归是一种典型的线性回归模型 它通过将线性回归模型的输出结果映射到 0 1 区间内 表示某个事物发生的概率 从而适用于二分类问题 具体地说 它使用sigmoid函数对线性回归模型的
  • Python的赋值与深浅拷贝

    简要版本 由于 Python 内部引用计数的特性 对于不可变对象 浅拷贝和深拷贝的作用是一致的 就相当于复制了一份副本 原对象内部的不可变对象的改变 不会影响到复制对象 浅拷贝的拷贝 其实是拷贝了原始元素的引用 内存地址 所以当拷贝可变对象
  • FLEX开发人员中心部分下载

    Adobe Application Modeling plug in download Adobe Application Modeling plug in download 点击进入 Flex MX Skin Design Extensi
  • C语言基础入门48篇_47_C语言操作文件(文件操作函数、打开文件fopen()、关闭文件fclose()、fclose规范程序、野指针的定义为:指针地址存在,但是指针指向的是一个已经释放的资源)

    本篇主要介绍c语言中对文件的打开关闭操作 1 C语言文件操作函数 C标准库中提供了一系列的函数 来操作文件 因为C库函数做了这个中间层 屏蔽掉了操作系统上对于文件的不同处理 关于文件的常见基本操作有 打开文件fopen 创建文件或打开文件载
  • 2020-6次面试阿里,持续一个多月,终于拿到offer了!

    从3月开始准备 一直到5月22号 终于拿到阿里的实习offer 这一路 真的是一把辛酸泪 下面细说之 在这一路上 坎坎坷坷 跌跌宕宕 期间 面了阿里 腾讯 百度 今日头条 小米 笔试网易 美团 携程 爱奇艺 不得不说 阿里是持续周期最长的
  • 视频爬虫逆向简单入门级

    严禁用于学习交流之外的任何用途 侵删 只能说这个比较简单 没什么难度 很适合做js逆向入门 下面就开始解析一下这个网站吧 aHR0cHM6Ly93d3cubWlndXZpZGVvLmNvbS9tZ3Mvd2Vic2l0ZS9wcmQvZGV
  • python中的爬虫基础工具介绍

    一 引入什么是爬虫 网络爬虫 按照一定的规则 自动地抓取互联网信息的程序 通俗的来讲 模拟用户端向服务器发送请求 批量获取数据的一种程序或 工具 方式 二 爬虫的分类 1通用爬虫 通用网络爬虫是捜索引擎抓取系统 Baidu Google S
  • 二进制部署k8s集群

    二进制部署k8s集群 1 安装要求 在开始之前 部署 Kubernetes 集群机器需要满足以下几个条件 一台或多台机器 操作系统 CentOS7 硬件配置 2GB 或更多 RAM 2 个 CPU 或更多 CPU 硬盘 30GB 或更多 集
  • 【JavaSE】常用类库1

    常用类库 1 对象清理 对象的清理 JDK1 9以前 使用Object中的finalize 方法 JDK1 9后 java lang ref Cleaner类 基于AutoCloseable接口资源释放 对象释放前 启动对象清理线程 pub
  • 20220128学习记录- 北交opencv基础

    1 模拟图像 空间采样与亮度量化 数字图像 空间分辨率 与采样间隔有关 亮度分辨率 与灰度级有关 2 图像存储 比特数 面积x灰度级的量化级别 注意是256灰度级不是乘256而是乘8 2的8次方 3 各类图像格式的特点与区别 4 灰度直方图
  • 什么是数据挖掘技术,基本概念是什么?

    随着计算机技术的发展 各行各业都开始采用计算机及相应的信息技术进行管理和运营 这使得企业生成 收集 存贮和处理数据的能力大大提高 数据量与日俱增 企业数据实际上是企业的经验积累 当其积累到一定程度时 必然会反映出规律性的东西 对企业来 堆积
  • JavaWeb-使用cookie完成两周内免登录功能

    欢迎页面 h2 欢迎页面 h2 br
  • 一文看懂异步 FIFO 架构(三) 双时钟的异步 FIFO

    目录 工作原理 方向标志 方向标志的实现 计算满和空 结论 往期系列博客 在本系列的第一篇文章中 我们看到了 FIFO 的一般架构 并分析了一个时钟的简单情况 该系列的第二部分描述了一种可能的双时钟设计的架构 在第三部分中 我们将探索另一种
  • Window操作系统基本知识

    windows系统 kernel32 dll是Windows 系统中非常重要的32位动态链接库文件 属于内核级文件 它控制着系统的内存管理 数据的输入输出操作和中断处理 当Windows启动时 kernel32 dll就驻留在内存中特定的写
  • 【CSS】滚动条样式详解

    只总结webkit的 IE与firefox暂不做记录 呼出与关闭滚动条 1 如果是浏览器的滚动条 其依赖的是html标签 我们不需要设置 内容溢出会自动出现 对html标签的溢出样式隐藏即可 html overflow x hidden 隐
  • 集合竞价规则及集合竞价的产生条件

    了解一下集合竞价规则 对于股民来说 是非常重要的 否则连一些基本的定义都了解不清楚的话 那么就麻烦了 下面为你介绍一下集合竞价规则以及集合竞价的产生条件 如果想要了解更多集合竞价方面的知识 敬请关注QR量化投资社区 下面让我们了解一下集合竞
  • 引入flutter module,运行时flutter_webview_plugin报错:Unhandled Exception: MissingPluginException

    异常信息 Android原生项目引入了一个flutter module flutter module用到了一个flutter写的sdk sdk需要使用webview来执行js代码 因此sdk引用了flutter webview plugin
  • mysql 分区表合并_MySQL 合并表、分区表

    合并表 合并表示一种早期的 简单的分区实现 在未来可能被淘汰 不推荐使用 限制 合并表和子表的字段 索引要完全相同 即使子表上有主键限制 合并表中仍然会出现重复值 如果删除其中一个子表 表可能还存在 带只能通过合并表访问 视操作系统而定 合
  • @GetMapping 接多个参数的写法

    后面拼接接着拼接上去就行了 此上方面针对于 接收多个未知参数 但是针对有很多需要模糊查询的方面 如果 我们所需要的接收的参数 是我们实体类对象的话 就不需要这么麻烦了 直接带入实体类对象 用即可
  • qt 串口通信

    qt串口通信 需要用到QSerialport类 1 pro文件中添加QT serialport 2 获取当前有哪些串口设备 QSerialPortInfo availablePorts 3 设置要打开的串口 setPortName 然后打开