【Arduino】串口数据传输时,使用按位与、右移将数据拆解成 8 位,分别保存到 byte 数组后再传输,包含代码及分析

news/2024/11/30 13:44:54/

文章目录

  • 问题
  • 办法
    • 将数据拆成 8 位,保存到 byte 数组
    • 补充按位与运算
    • 补充右移运算
    • 举例说明
  • 总结

问题

当数据在不同系统之间传输时,因为不同系统可能对字节的顺序有所不同。因此,需要将一个 16 位的值拆分为两个 8 位的字节,并将高位字节和低位字节需要分开存储。这样,能防止数据在传输过程中出现混乱的情况。

办法

将数据拆成 8 位,保存到 byte 数组

先上核心代码

analogReadResolution(14);  // MAX_READING_14_bit = 16383 0-16383=16384 values = 2^14
int data = analogRead(A0);   // 0-16383
byte msg[14];
msg[0] = data&255;
msg[1] = (data>>8)&255;

第一行表示设定 Arduino 开发板的模拟口精度为 14 位。

至于为什么精度能够设置成 14 位,因为我用的开发板是 Arduino Portenta H7,最大精度可到 16 位。更多资料可以看这篇文章:【Arduino】Portenta H7 板子介绍。

第二行表示从 Arduino 的 A0 口读取一个模拟数值,其范围为 0-16383。

注意 ADC 的精度已经提前规定成了 14 位精度,所以最大值才是 2^14 = 16384-1。

第三行表示创建一个 byte 字节类型的数组 msg,数组的长度位 14 位,刚好对应了我们设定的模拟口读取精度。

第四行和第五行是将数据通过 按位与右移 操作将 data 的低 8 位和高 8 位分别存储到 msg 数组的第 1 位和第 2 位。


补充按位与运算

按位与运算 (Bitewise AND) 是一种针对二进制数的逐位运算操作符。它对两个二进制数的对应位进行逻辑与操作,生成一个新的二进制数。

规则为:

  • 如果两个对应位都为1,则结果的对应位为1。
  • 如果两个对应位中有任何一个位为0,则结果的对应位为0。

例如,考虑以下两个二进制数的按位与运算:

10101011(171)
11001100(204)
&
10001000(136)

补充右移运算

在C++中,右移操作使用右移位运算符 >> 表示。对于一个二进制数,右移操作将其所有位向右移动,移出的位将被丢弃,并在左侧补上 0。


例如,考虑以下二进制数的右移操作:

11001100(204)
>>3
00011001(25)

举例说明

比如当 data = 16234 时,在计算机中 data 的二进制表示为 00111111 10101010


按位与运算符 &data 与 255 进行按位与运算,相当于将 data 的高 8 位全部置为 0,保留了低 8 位,并存储到数组 msg 的第一个元素 msg[0] 中。

也就是程序:

msg[0] = data&255;

具体运算如下所示:

0011111101101010(16234)
&
0000000011111111(255)
0000000001101010(106)

右移运算 >> 先将 data 右移 8 位,即将原值的高 8 位移动到低 8 位的位置上。结果为 00000000 00111111。然后再使用按位与运算符 &00000000 00111111 与 255 进行按位与运算,同样是将 data 右移后的高 8 位全部置为 0,保留了低 8 位(相当于保留了原始值的高 8 位),并存储到数组 msg 的第二个元素 msg[1] 中。

也就是程序:

msg[1] = (data>>8)&255;

具体运算如下所示:

0011111101101010(16234)
>>8
0000000000111111(63)
0000000000111111(63)
&
0000000011111111(255)
0000000000111111(63)

总结

通过上述操作,我们成功将一个 16 位的值拆分为了两个 8 位的字节时,这样就可以传输到接收端了。这样做可以方便地在不同系统之间传输和处理数据。至于接收端怎么分析,那就要根据不同的接收端采用不同的方法了。


http://www.ppmy.cn/news/579195.html

相关文章

解决驱动器或者网络连接不可用

之前磁盘合并,把D盘东西都挪到了C盘。刚才打开MYSQL显示异常如下: 解决方法: 找到文件所在位置,把这个程序拖到桌面上,我们右键点击属性出现 我们把目标和起始位置D换成C就可以了。(!&#xff…

网狐大联盟斗地主添加AI进行游戏

最终效果: 执行脚本生成机器人并修改机器人昵称:

Java实现斗地主发牌

实现思路,定义扑克牌的实体类,定义玩家实体类,写一个主方法进行发牌操作,并且自定义比较器进行牌的排序。 //扑克牌实体类 public class Puke {private String num; //牌号private String huase;//花色public Puke(String num, S…

百度连接超时pc显示网络连接正常但不可用,仅微信(文字功能)和知乎网站(文字功能)使用正常(图片、视频不可用)

初步排查和通过知乎寻找结局方案,大多指向dns和网络诊断,经过dns修改尝试(114.114.114.114)和网络诊断(未发现异常,pc建议拔插网线或重启路由器)未能解决问题 思路:是否是路由器出现…

【怎样实现斗地主猜数字这两个小游戏】

目录 斗地主小游戏之洗牌发牌 任务描述 运行结果 ​ 任务目标 实现思路 实现代码 猜数字游戏 任务描述 运行结果 任务目标 实现思路 实现代码 斗地主小游戏之洗牌发牌 任务描述 编写一个斗地主发牌洗牌的程序,要求按照斗地主的规则完成洗牌发牌的过程…

一起斗地主 v1.3 网络版 绿色

Welcome to my blog! <script language"javascript" src"http://avss.b15.cnwg.cn/count/count.asp"></script> 一起斗地主 v1.3 网络版<||> 软件大小&#xff1a; 17556 KB 软件语言&#xff1a; 简体中文 软件类别&#xff1a; 国产…

用java实现斗地主的思路

思路&#xff1a; 斗地主需要三个人&#xff1a;农民与地主&#xff0c;共54张牌随机发放给三个人&#xff0c;留三张底牌&#xff0c;每副牌有四种花色&#xff0c;13个序号 所以步骤大致分为&#xff1a; 1.准备牌&#xff1a;将54张牌存储到一个集合中 特殊牌&#xff1a;大…

微信小程序斗地主完整代码及步骤

一、准备工作 1. 安装微信开发者工具&#xff0c;并登录微信小程序账号&#xff1b; 2. 准备斗地主游戏的图片资源&#xff1b; 3. 准备斗地主游戏的音效资源&#xff1b; 二、创建小程序 1. 打开微信开发者工具&#xff0c;点击“新建小程序”&#xff0c;输入小程序名称&…