原文链接:https://blog.csdn.net/qq_34322603/article/details/106457231
QByteArray在串口通讯中经常被使用,通信处理过程中,经常会涉及到数据格式的转换,有一定必要较为全面详细的对QByteArray数据转换与处理部分进行阐述。本文通过以下几个部分加以介绍:
在使用串口发送数据时可以选择字符串发送或者十六进制发送,通常情况下我们习惯选用字符串发送数据。关于两者的区别,需要从计算机存储数据的格式说起。
在计算机中,数据是以二进制的形式存储的,例如十进制 1(10)在计算机中用 0000 0001(2)来表示。在使用字符串方式发送数据的时候,串口软件首先将待数据转换为对应的ASCII码,然后再将这些ASCII码按照二进制的方式一位一位的发送出去;而使用十六进制方式发送数据的时候,串口直接将数据以二进制的方式一位一位的发送出去。
例如我们在串口软件发送框输入 “FF012345”,分别以字符串和十六进制两种方式发送:
串口以字符串发送数据,首先将字符串转化为ASCII码对应的二进制,格式如下
串口发送了8个字节,若在接收端选择字符串接收,则会接收到FF0123456这个字符串;若在接收端选择十六进制接收,则会接收到:
0100 0110 | 0100 0110 | 0011 0000 | 0011 0001 | 0011 0010 | 0011 0011 | 0011 0100 | 0011 0101 这一串数字
串口以十六进制发送数据,首先将发送框中数据转化为如下格式:
串口发送了4个字节,若在接收端选择十六进制接收,则会在接收框显示FF 01 23 45;若在接收端选择字符串接收,则会接收到乱码
仔细对照接收结果就很容易明白字符串发送和十六进制发送的区别了。
从串口读取到的QByteArray数据,一般需要进行提取和解析,此时就需要QByteArray转换为各类型数据。常用转换包括:
1、字符与十六进制转换,例如串口接收到的数据,用字符方式表达,或者将字符串对应的十六进制数据流转化为字符串;
2、转为不同进制数值并显示,如二进制、八进制、十进制和十六进制等;
3、转为整型、浮点型等数值类型;
4、大小写转换;
5、转为字符串类型;
把Hex编码的数据流转换为char存储到QByteArray:
QByteArray text = QByteArray::fromHex("517420697320677265617421");
text.data(); // "Qt is great!"
把QByteArray数据转换为字符串:
QByteArray ba;
ba.resize(3);
ba[0] = 0x30;
ba[1] = 0x31;
ba[2] = 0x32;
qDebug() << ba.toHex(); //return "303132"
尽管QByteArray是一个集合,但也可以作为一个特殊形式的数值用,其灵活的转换格式,可大大方便各种格式数据转换与显示的需求。如显示二进制和十六进制、显示科学计数和指定小数位的数值。示例如下:
把单个字符转为2-36进制数据格式:
int n = 63;
qDebug()<<QByteArray::number(n); // returns "63"
qDebug()<<QByteArray::number(n, 16); // returns "3f"
qDebug()<<QByteArray::number(n, 16).toUpper(); // returns "3F"
qDebug()<<QByteArray::number(n, 2); // returns "111111"
qDebug()<<QByteArray::number(n, 8); // returns "77"
按照指定进制格式直接复制,其中n可以是各类常见数值类型:
int n = 63;
qDebug()<<QByteArray::number(n); // returns "63"
qDebug()<<QByteArray::number(n, 16); // returns "3f"
qDebug()<<QByteArray::number(n, 16).toUpper(); // returns "3F"
qDebug()<<QByteArray::number(n, 2); // returns "111111"
qDebug()<<QByteArray::number(n, 8); // returns "77"
按照指定进制格式直接复制,其中n可以是各类常见数值类型:
QByteArray ba;
int n = 63;
ba.setNum(n); // ba == "63"
ba.setNum(n, 16); // ba == "3f"
把数值按指定格式和小数位转换输出,小数位四舍五入:
QByteArray ba1 = QByteArray::number(12.3456, 'E', 3);
QByteArray ba2 = QByteArray::number(12.3456, 'f', 3);
qDebug()<<ba1; // returns "1.235E+01"
qDebug()<<ba2; // returns "12.346"
QByteArray若为数值,可通过to**方法转为各种类型数据,示例如下:
QByteArray strInt("1234");
bool ok0;
qDebug() << strInt.toInt(); // return 1234
qDebug() << strInt.toInt(&ok0,16); // return 4660, 默认把strInt作为16进制的1234,对应十进制数值为4660
QByteArray string("1234.56");
bool ok1;
qDebug() << string.toInt(); // return 0, 小数均视为0
qDebug() << string.toInt(&ok1,16); // return 0, 小数均视为0
qDebug() << string.toFloat(); // return 1234.56
qDebug() << string.toDouble(); // return 1234.56
QByteArray str("FF");
bool ok2;
qDebug() << str.toInt(&ok2, 16); // return 255, ok2 == true
qDebug() << str.toInt(&ok2, 10); // return 0, ok == false, 转为十进制失败
QByteArray若为带大小写的字符串,可通过toUpper()和toLower()方法实现大小写转换,示例如下:
QByteArray x("Qt by THE QT COMPANY");
QByteArray y = x.toLower();
// y == "qt by the qt company"
QByteArray z = x.toUpper();
// z == "QT BY THE QT COMPANY"
QByteArray与QString互转极为简单,二者从本质上类似,都是连续存储,区别是前者可以存无法显示的字符,后者只存可显示的字符。如QByteArray可以存0x00-0x19,而QString则存储如0x30等可显示字符(0x20-0x7E)。可显示字符可参见ASCII表,链接如下:ASCII可显示字符
QByteArray转为QString示例:
QByteArray ba("abc123");
QString str = ba;
//或str.prepend(ba);
qDebug()<<str ;
//输出:"abc123"
QString转为QByteArray示例:
QString str("abc123");
QByteArray ba = str.toLatin1();
qDebug()<<ba;
//输出:"abc123"
(用于读取textEdit中的字符串数据,并转换为16进制数据,用于串口通信)
例:如果某次传输的数据为0x30 0x38 0x0D 0x32(二进制原始数据),从输入控件textEdit中输入30 38 0D 32,此时从textEdit读取的为字符串"30 38 0D 32",所以要将其转换为二进制0x30 0x38 0x0D 0x32,存入QByteArray中。
QString str1 = ui->lineEdit_SendCmd->text();
QByteArray cmd = QByteArray::fromHex(str1.toLatin1().data()); //按照十六进制编码接入文本
同理:将二进制数据转换为字符串:
ba.resize(3);
ba[0] = 0x30;
ba[1] = 0x31;
ba[2] = 0x32;
qDebug() << ba.toHex(); //return "303132"
//注意收发两端文本要使用对应的编解码
const QByteArray recv_test = socket->readAll();
dataParse(recv_test);
//qDebug()<<"recv msg:"<<recv_test;
QString ret;
QByteArray ba = recv_test.toHex(' ');
qDebug()<<"ba: "<<ba;
//for (int i=0; i<recv_test.count(); ++i) {
//ret.append(tr("%1 ").arg((quint8)recv_test.at(i),2,16,QLatin1Char('0')).toUpper());
//}
ui->textEdit_message->append(ba.toUpper()); // ret换成ba
//接收串口数据以字符和十六进制数据显示
QByteArray temp = myCom->readAll();
//读取串口缓冲区的所有数据给临时变量temp
ui.textBrowser->insertPlainText(temp);
ui.textEdit_2->insertPlainText(temp.toHex());
//将串口的数据显示在窗口的文本浏览器中
文章浏览阅读1.7w次,点赞2次,收藏13次。<v:shapetypeid="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:shape id="_x0000_i102
文章浏览阅读532次。{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台;社区覆盖了云计算、大数据、人工智能、IoT、云原生、数据库、微服务、安全、开发与运维9大技术领域。","link1":..._python 执行cmd命令 的输出
文章浏览阅读456次。【README】消息中心的消息追踪需要使用 Trace 实现,Trace是 rabbitmq用于记录每一次发送的消息;方便开发者调试,排错。可通过插件形式提供可视化界面。【1】 开启消息追踪1)消息追踪通过 rabbitmq的插件 trace 来实现, 插件需要启用和打开;2)trace 启动后会自动创建系统 Exchange, amq. rabbitmq.trace, 每个队列会自动该绑定该exchange,绑定后发送到队列的消息都会发送到 trace 日志;3)插件命令序号 _rabbitmq rabbitmq_tracing
文章浏览阅读2k次,点赞3次,收藏25次。1. 导入所需的库import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltfor i in [tf, np]: print(i.__name__,": ",i.__version__,sep="")输出:tensorflow: 2.2.0numpy: 1.17.42. 导入Fashion_MNIST数据集fashion_mnist = tf.keras.datasets.fas_difussion model mnist
文章浏览阅读693次。点击ppt中的某一张图片,上边工具栏会出现压缩图片的选项。_wps ppt压缩
文章浏览阅读9.4k次。如果需要在网页中添加视频,可以参考下面的代码,支持MP4视频自动循环播放。纯HTML5视频自动循环播放HTML>不过火狐浏览器貌似默认禁止自动播放音频视频,需要到选项 → 隐私与安全 → 自动播放,设置允许音频和视频。如果不设置就可以自动播放,可以使用代码二。配合JS自动循环播放html>HTML5视频自动循环播放window.onload=function(){varloca..._video html播放快结束的时候一直循环最后几秒
文章浏览阅读1k次,点赞27次,收藏16次。kaldi是一个开源的语音识别工具箱,是基于c++、perl、shell编写的,可以在windows和unix 平台上编译。教程网页:http://www.kaldi-asr.org/doc/ 里面可以查阅语音/说话人识别实现过程、kaldi的数据结构、命令的使用说明等。还有网上的dan的ppt。kaldi下载:https://_利用 kaldi 进行语音识别
文章浏览阅读2k次。互素定义互素也称互质,是指公约数只有1的两个数,如2和3、2和5、3和5等等。matlab函数简单介绍factor(n):对一个数而言是做质数分解,如factor(4),输出为2,2;factor(5),输出为5;factor(9),输出为3,3。factor(f):对一个函数进行因式分解,如f=x2−1f = x^2 - 1f=x2−1输出结果为:[x+1,x−1x + 1, x - 1x+1,x−1]。intersect()函数:求两个集合的交集,如A = [1, 2, 3],B = [3]_matlab 随机生成互质数
文章浏览阅读638次。【项目实战】基于大数据的Hadoop网络电商分析系统Hive数据可视化大屏展示Spark计算机程序设计_大数据处理与分析实训:用hive处理和分析给定的电商数据,并将分析结果进行可视化展
文章浏览阅读58次。一、前言课程名称:软件工程实践作业要求:团队项目需求分析团队名称:葫芦娃战队本次作业目标:完成项目需求说明书软件规格需求说明书:https://files.cnblogs.com/files/beifengtuanzi/%E8%91%AB%E8%8A%A6%E5%A8%83%E9%9C%80%E6%B1%82%E8%AF%B4%E6%98%8E%E4%B9%A6.zip需求报告PPT...
文章浏览阅读1.4k次。Linux man命令数字含义 1 User Commands 2 System Calls 3 C Library Functions 4 Devices and Special Files 5 File Formats andConventions _man 3 printf与man 1 printf有何区别?这里的数字的意义是什么
文章浏览阅读1.2k次,点赞2次,收藏5次。#include "stc15f2k60s2.h"#include "nrf.h"#include "oled.h"#include "usart.h"#include "motor.h"#define L_UPPER_LIMIT 240 ..._遥控车程序c代码