2

我正在对我的 Arduino 微控制器进行编程,并且我找到了一些用于接受加速度计传感器数据以供以后使用的代码。我可以理解除以下代码之外的所有内容。我想对正在发生的事情有一些直觉,但经过所有的搜索和阅读,我无法完全理解正在发生的事情并真正理解。

我上过一门 C++ 课程,但我们很少使用按位运算或位移或任何你喜欢的名称。让我试着解释一下我认为我理解的内容,你可以在需要的地方纠正我。

所以:

  1. 我认为我们在 x 中存储了一个值,事实上非常确定。
  2. 似乎数组“buff”中的数据,插槽号 1,被设置为整数数据类型。
  3. 插槽 1 中的值向左移动了 8 位。(这是否指向 buff 插槽 0?)

这个新值正在与 buff slot 0 中的数据进行比较,如果任一位为真,则存储在 x 中的数据中的位也将为真,因此,0 和 1 = 1、0 和 0 = 0 和 1 和 0 = 1 到底存储的值。

代码对所有三个轴执行此操作:x、y、z 但我不知道为什么......我需要帮助。在我进步之前,我希望得到充分的理解。

//each axis reading comes in 10 bit resolution, ie 2 bytes.  
// Least Significant Byte first!!
//thus we are converting both bytes in to one int
x = (((int)buff[1]) << 8) | buff[0];   
y = (((int)buff[3]) << 8) | buff[2];
z = (((int)buff[5]) << 8) | buff[4];
4

4 回答 4

4

此代码用于将原始加速度计数据(6 字节数组)转换为三个 10 位整数值。正如评论所说,数据首先是 LSB。那是:

buff[0] // least significant 8 bits of x data
buff[1] // most significant 2 bits of x data 
buff[2] // least significant 8 bits of y data
buff[3] // most significant 2 bits of y data 
buff[4] // least significant 8 bits of z data
buff[5] // most significant 2 bits of z data 

它使用按位运算符将两个部分放在一个变量中。(int)类型转换是不必要的并且(恕我直言)令人困惑。这个简化的表达式:

x = (buff[1] << 8) | buff[0];

将数据放入buff[1],并将其向左移动 8 位,然后将 8 位放入buff[0]如此创建的空间中。a例如,让我们标记这 10 位j

buff[0] = cdefghij
buff[1] = 000000ab

然后:

buff[1] << 8 = ab00000000

和:

buff[1] << 8 | buff[0] = abcdefghij
于 2013-08-20T20:23:18.567 回答
1

插槽 1 中的值向左移动了 8 位。(这是否指向 buff 插槽 0?)

不。位运算符不是指针运算,不要混淆两者。向左移动N位置(大致)相当于乘以 2 的Nth 次方(C 中的一些极端情况除外,但我们先不讨论这些情况)。

这个新值正在与 buff slot 0 中的数据进行比较,如果任一位为真,则存储在 x 中的数据中的位也将为真

|,不是逻辑 OR 运算符(即||),而是按位 OR 运算符。代码所做的只是将两个字节组合成一个 2 字节整数,其中buff[0]表示数字的 MSB。buff[1]buff[1]

于 2013-08-20T20:20:27.520 回答
0

设备结果为 6 个字节,字节需要重新排列为 3 个整数(具有最多只能占用 10 位的值)。

所以前两个字节如下所示:

00: xxxx xxxx <- binary value
01: ???? ??xx

这 ???部分不是结果的一部分,因为 xxx 部分包含 10 位。我猜硬件的构建方式是 ??? 部分全为零位。

要将其转换为单个整数变量,我们需要所有 8 个低位加上高 2 位,左移 8 个位置,这样它们就不会干扰低 8 位。逻辑 OR(| - 竖线)会将这两个部分连接成一个整数,如下所示:

x: ???? ??xx xxxx xxxx <- binary value of a single 16 bit integer

实际上,“int”有多大(以位为单位)并不重要,因为在这种情况下,剩余的位(超过 16 位)将为零。

于 2013-08-20T20:24:15.457 回答
0

扩大和澄清 Carl Norum 的答复。

(int) 类型转换是必需的,因为源是一个字节。在将结果保存到 X 之前对源数据类型执行位移。因此,必须将其转换为至少 16 位(一个 int)才能位移 8 位并在执行 OR 操作和结果之前保留所有数据保存。

代码没有告诉您的是这是否应该是一个无符号整数或位数据中是否有符号。我希望加速度计可以提供 -ve 数据。

于 2017-03-13T15:39:14.223 回答