基于Qt的串口调试工具串口常见问题

news/2024/11/17 21:36:01/文章来源:https://www.cnblogs.com/ahsczj/p/18426257

1.项目地址

https://github.com/zhangjiechina001/SerialPortTool

2.使用注意

  1. 串口的所有参数波特率、数据位、校验位、停止位、控制流都需要设置正确,设置错了有时会连接上但是传输的数据会很奇怪,有时直接连接不上了
  2. 串口通信中一般不需要像网络通信那样明确的保活机制(Keep-alive),因为串口通信是基于硬件的点对点连接,没有复杂的中间路由设备或网络超时的问题。然而,在某些场景下,使用保活机制还是有意义的,尤其是在需要保持长时间稳定通信的场景下,以防止通信中断或检测设备故障。实现方式:
    心跳包: 定期发送一小段固定的数据,等待接收方的响应。如果没有在一定时间内收到响应,可以重新建立连接或处理错误。
    超时机制: 如果在规定时间内没有接收到数据或响应,触发超时处理。
    错误检测: 结合串口的错误处理机制,例如 QSerialPort::timeout() 或 QSerialPort::error(),可以检测到超时或其他错误。
    在大多数简单的串口应用中,保活机制可能不是必需的。但对于长时间运行或对可靠性要求较高的应用,引入保活机制能提高系统的健壮性。

3.串口通讯参数解释

串口通讯(Serial Communication)是一种逐位传输数据的通信方式,常见于计算机与外部设备(如传感器、微控制器等)之间的通信。串口通讯的参数包括以下几个常见项:

  1. 波特率(Baud Rate):
    波特率表示每秒传输的符号数(位元数),即每秒钟可以传输多少个比特。常见的波特率有9600、19200、115200等。发送端和接收端必须使用相同的波特率。

  2. 数据位(Data Bits):
    数据位表示每次传输的实际数据位数,通常是5到8位。最常见的是8位数据位(即一个字节),用于传输一个完整的字符。

  3. 停止位(Stop Bits):
    停止位用于标志一帧数据的结束,常见的停止位为1位或2位。停止位的作用是给接收端一些时间来处理接收到的数据,并为下一帧做准备。

  4. 校验位(Parity Bit):
    校验位用于检测传输过程中是否出现错误。常见的校验方式有:
    无校验(None):不使用校验位。
    偶校验(Even Parity):如果传输的数据位中“1”的个数是偶数,校验位为0;否则为1。
    奇校验(Odd Parity):如果传输的数据位中“1”的个数是奇数,校验位为0;否则为1。

  5. 流控制(Flow Control):
    流控制用于控制数据的传输速率,确保接收方有足够的时间处理数据。常见的流控制方式包括:
    无流控制(None):不进行流控制。
    软件流控制(XON/XOFF):通过特殊的控制字符(XON 和 XOFF)来控制数据的传输。
    硬件流控制(RTS/CTS):使用额外的控制线(RTS 和 CTS)来协调数据的发送和接收。
    起始位(Start Bit):

  6. 起始位用于标志数据帧的开始,通常为1位。在传输数据之前,发送端会发送起始位,接收端以此为标志开始接收数据。

这些参数通常需要在通信的双方(如计算机和串口设备)之间进行配置,以确保数据能够正确传输。如果参数不一致,可能会导致数据丢失或接收错误。

4.核心类

头文件

#ifndef SERIALPORTWRAP_H
#define SERIALPORTWRAP_H
#pragma execution_character_set("utf-8")
#include <QObject>
#include <QSerialPort>class SerialPortWrap : public QObject
{Q_OBJECT
public:static QMap<QString,QSerialPort::Parity> getParityMap();static QMap<QString,QSerialPort::DataBits> getDataMap();static QMap<QString,QSerialPort::StopBits> getStopMap();static QMap<QString, QSerialPort::FlowControl> getFlowMap();public:explicit SerialPortWrap(QObject *parent = nullptr);void setSerialPort(QSerialPort *port);bool sendNoReply(QByteArray data);bool sendReply(QByteArray data, QByteArray &rec);signals:void receivedData(QByteArray data);public slots:private:QSerialPort *_serial=nullptr;QList<QByteArray> _recList;void waitMs(int ms);private slots:void onError(QSerialPort::SerialPortError err);void onReadyReady();
};#endif // SERIALPORTWRAP_H

cpp

#include <QMap>
#include <QDebug>
#include <QEventLoop>
#include <QElapsedTimer>
#include <QTimer>
#include "serialportwrap.h"QMap<QString, QSerialPort::Parity> SerialPortWrap::getParityMap()
{QMap<QString,QSerialPort::Parity> parityMap={{"NoPraity",QSerialPort::NoParity},{"EvenParity",QSerialPort::EvenParity},{"OddParity",QSerialPort::OddParity},{"SpaceParity",QSerialPort::SpaceParity},{"MarkParity",QSerialPort::MarkParity}};return parityMap;
}QMap<QString, QSerialPort::DataBits> SerialPortWrap::getDataMap()
{QMap<QString,QSerialPort::DataBits> dataMap={{"Data5",QSerialPort::Data5},{"Data6",QSerialPort::Data6},{"Data7",QSerialPort::Data7},{"Data8",QSerialPort::Data8}};return dataMap;
}QMap<QString, QSerialPort::StopBits> SerialPortWrap::getStopMap()
{QMap<QString,QSerialPort::StopBits> stopMap={{"OneStop",QSerialPort::OneStop},{"OneAndHalfStop",QSerialPort::OneAndHalfStop},{"TwoStop",QSerialPort::TwoStop}};return stopMap;
}QMap<QString, QSerialPort::FlowControl> SerialPortWrap::getFlowMap()
{QMap<QString,QSerialPort::FlowControl> flowMap={{"NoFlowControl",QSerialPort::NoFlowControl},{"HardwareControl",QSerialPort::HardwareControl},{"SoftwareControl",QSerialPort::SoftwareControl},{"UnknownFlowControl",QSerialPort::UnknownFlowControl}};return flowMap;
}SerialPortWrap::SerialPortWrap(QObject *parent) : QObject(parent)
{}void SerialPortWrap::setSerialPort(QSerialPort *port)
{_serial=port;connect(_serial,&QSerialPort::errorOccurred,this,&SerialPortWrap::onError);connect(_serial,&QSerialPort::readyRead,this,&SerialPortWrap::onReadyReady);
}bool SerialPortWrap::sendNoReply(QByteArray data)
{_recList.clear();return  _serial->write(data)!=-1;
}bool SerialPortWrap::sendReply(QByteArray data,QByteArray &rec)
{_recList.clear();_serial->write(data);QElapsedTimer ela;ela.start();while(_recList.count()==0){waitMs(100);if(ela.elapsed()>3000){throw QString("%1 time out").arg(_serial->portName());}}waitMs(50);QByteArray arr;for(int i=0;i<_recList.count();i++){arr.append(_recList.at(i));}rec=arr;return true;
}void SerialPortWrap::waitMs(int ms)
{QEventLoop loop;QTimer::singleShot(ms, &loop, &QEventLoop::quit);  // 设置定时器,在超时时退出事件循环loop.exec();  // 进入事件循环
}void SerialPortWrap::onError(QSerialPort::SerialPortError err)
{qDebug()<<__FUNCTION__<<__LINE__<<_serial->portName()<<_serial->errorString();
}void SerialPortWrap::onReadyReady()
{QByteArray arr=_serial->readAll();_recList.append(arr);emit receivedData(arr);
}

5.效果图:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次 RabbitMQ 消费者莫名消失问题的排查

开心一刻 今天好哥们找我借钱哥们:兄弟,我最近手头紧,能不能借我点...我:我手头也不宽裕,要不你试试银行贷款或者花呗?哥们:不行,那个借了要还的我:...问题回顾 某天下午,生产监控告警:消息积压,队列 xxx 消息数超过 100;我第一时间想到的是应用服务是不是停了,但…

大模型应用开发初探 : 快速直观感受RAG

检索增强生成(Retrieval Augmented Generation),简称 RAG,它是根据用户输入的提示词,通过自有垂域数据库检索相关信息,然后合并成为一个新的“完备的“提示词,最后再给大模型生成较为准确的回答。这一篇,我们来快速了解下RAG(检索增强生成)并通过一个简单的DEMO来直观…

Adobe After Effects 2024 v24.6.2 (macOS, Windows) 发布下载 - 后期特效

Adobe After Effects 2024 v24.6.2 (macOS, Windows) 发布下载 - 后期特效Adobe After Effects 2024 v24.6.2 (macOS, Windows) - 后期特效 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、…

Unity中的光源类型(向前渲染路径进行光照计算)

Unity中的光源类型 Unity中共支持4种光源类型:平行光 点光源 聚光灯 面光源(在光照烘焙时才可以发挥作用)光源的属性:位置 方向(到某个点的方向) 颜色 强度 衰减(到某个点的衰减)平行光 平行光的几何定义是最简单的,平行光可以照亮的范围是无限远的,且对与场景中的各…

Adobe Photoshop 2024 v25.12 (macOS, Windows) 发布下载 - 照片和设计软件

Adobe Photoshop 2024 v25.12 (macOS, Windows) 发布下载 - 照片和设计软件Adobe Photoshop 2024 v25.12 (macOS, Windows) - 照片和设计软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesig…

C#/.NET/.NET Core技术前沿周刊 | 第 6 期(2024年9.16-9.22)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿,推荐或自荐优质文章/项目/学习资源等。…

基础数据结构之数组

数组 1) 概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识In computer science, an array is a data structure consisting of a collection of elements (values or variables), each identified by at least one ar…

网站搭建

第一步,服务器申请选择一:免费云服务器,免费虚拟主机 如:阿贝云阿贝云提供了免费的云服务器和免费的云虚拟主机,可根据自己的实际应用情况选择。 首先注册一个账户,然后需要支付0.3元做一个实名认证,如果实名认证成功了大概率会开通成功。如果失败了可能是服务器资源池不…

读构建可扩展分布式系统:方法与实践12分布式数据库案例

分布式数据库案例1. Redis 1.1. 2009年首次发布1.1.1. 更注重原始性能和简单性,而不是数据安全性和一致性1.2. 主要吸引力在于它能够同时充当分布式缓存和数据存储 1.3. 维护一个内存中的数据存储,也称为数据结构存储(data structure store) 1.4. 配置Redis将每个命令记录到一…

Java代码审计篇 - ofcms系统审计思路讲解 - 篇2 - SQL注入漏洞审计

Java代码审计篇 | ofcms系统审计思路讲解 - 篇2 | SQL注入漏洞审计 1. 前言 我发现很多文章包括教程,大概套路是:只说有漏洞的点,将有漏洞的点指出,然后分析代码;或者黑盒测试出漏洞之后,然后分析代码。 我认为这是在分析漏洞代码,而非代码审计。代码审计文章或教程应该…