Binary 转换两个';s补码,将左对齐整数转换为正则二进制 我在C++和QT中编程树莓PI 3。我使用该库与I2C加速计接口(我使用该加速计比较倾斜角度值,但不测量角度)

Binary 转换两个';s补码,将左对齐整数转换为正则二进制 我在C++和QT中编程树莓PI 3。我使用该库与I2C加速计接口(我使用该加速计比较倾斜角度值,但不测量角度),binary,type-conversion,raspberry-pi3,Binary,Type Conversion,Raspberry Pi3,我需要确定一个加速计读数是否大于或小于前一个读数,或者是否具有任意预设值。(我想将机器上的手臂设置为任意角度,然后让手臂在该角度之间来回移动。) 加速计以两个字节的两个互补数据输出读数。数据是12位左对齐的。(我假设这意味着加速计值的4个最高有效位位于上字节的左侧?)加速计是LIS3DH 我正在将两个字节作为两个整数值读入我的程序中,但我正在努力将数据转换为有用的信息 wiringPi I2C库只返回整数 我可能需要将十进制读数转换成二进制,将两个字节的两个字节的左对齐二进制数据转换成12位右对

我需要确定一个加速计读数是否大于或小于前一个读数,或者是否具有任意预设值。(我想将机器上的手臂设置为任意角度,然后让手臂在该角度之间来回移动。)

加速计以两个字节的两个互补数据输出读数。数据是12位左对齐的。(我假设这意味着加速计值的4个最高有效位位于上字节的左侧?)加速计是LIS3DH

我正在将两个字节作为两个整数值读入我的程序中,但我正在努力将数据转换为有用的信息

wiringPi I2C库只返回整数

我可能需要将十进制读数转换成二进制,将两个字节的两个字节的左对齐二进制数据转换成12位右对齐的常规二进制数据

我正在寻找关于如何实现这一点的建议,以及是否有比我上面列出的路径更简单的方法来实现这一点

编辑:

编辑:
非常感谢罗曼。我提出了相同的基本概念,但似乎两个寄存器颠倒了。再次感谢。

根据LIS3DH(ADC有10位)上的说明,您应该执行以下操作:

unsigned int result = ((acc_h & 0x03)<<8) + (acc_l & 0xFF);

unsigned int result=((acc_h&0x03)我也在使用LIS3DH,经过几个小时的阅读和尝试,我终于找到了答案。虽然我的代码是针对AVR微控制器的,但方法还是一样的

加速计以左对齐的16位值表示其读数,每个轴分为2字节寄存器:
OUT\u X\u L
OUT\u X\u H
OUT\u Y\u L
OUT\u Y\u H
OUT\u Z\u H
。左对齐意味着:所有值位都向左移动。多少位?这取决于你的精准度

假设使用10位精度(默认值),并且希望读取X轴值,则
OUT\u X\u H
OUT\u X\u L
寄存器将如下所示:

╔═════════╦═══════════╦═══════════╗
║         ║  OUT_X_H  ║  OUT_X_L  ║
╠═════════╬═══════════╬═══════════╣
║ Content ║ xxxx xxxx ║ xx00 0000 ║
╚═════════╩═══════════╩═══════════╝
x-是您想要的值,0只是一个零。因为精度是10位,所以6个低有效位将始终为零

为什么有人会希望发送这样的数据?原因很简单——如果你不关心精度,你可以只读取高位寄存器,并将其存储为8位整数(
int8\t
)。由于左对齐,保留了更多的最高有效位,并且从低位寄存器仅丢失2位。另一方面,右对齐更易于操作,但如果不读取整个16位值,则会丢失大量信息

现在,如果要将此值转换为“正常”值(右对齐),则需要将其存储为16位整数(
int16\t
).计算机将有符号整数作为2的补码,LIS3DH也是如此,这意味着存储在这个
int16\t
变量中的值将有一个正确的符号。你必须做的最后一个操作是将这个值右移6位(10位精度),瞧

我已经编写了两种转换方法,一种是基于典型的位操作,另一种是指针转换

位操作 对于每个轴:

  • 以字节数组存储寄存器。元素顺序仅对小端结构有效。对于大端结构,高位寄存器应位于第一位。
  • uint8\u t
    指针转换为
    int16\u t
    指针,因此指向字节数组的指针被视为指向一个16位整数的指针,对其进行解引用,然后右移6

  • 你们有可以发布的代码吗?有符号整数的右移是实现定义的。确保你们的编译器执行“算术右移”要使此解决方案与负数一起工作,需要了解这一点:它确实是实现定义的,如何以可移植的方式做到这一点?问题是,首先需要将其转换为int,然后删除LSB零,符号位必须保持存在
    unsigned int result = ((acc_h & 0x0F)<<8) + (acc_l & 0xFF);
    
    ╔═════════╦═══════════╦═══════════╗
    ║         ║  OUT_X_H  ║  OUT_X_L  ║
    ╠═════════╬═══════════╬═══════════╣
    ║ Content ║ xxxx xxxx ║ xx00 0000 ║
    ╚═════════╩═══════════╩═══════════╝
    
    int16_t x = out_x_h; // 1.
    x <<= 8;             // 1.
    x |= out_x_l;        // 2.
    x >>= 6;             // 3.
    
    int16_t y = out_y_h;
    y <<= 8;
    y |= out_y_l;
    y >>= 6;
    
    int16_t z = out_z_h;
    z <<= 8;
    z |= out_z_l;
    z >>= 6;
    
    uint8_t x_a[2] = {out_x_l, out_x_h}; // 1.
    int16_t x = (*(int16_t*) x_a) >> 6;  // 2.
    
    uint8_t y_a[2] = {out_y_l, out_y_h};
    int16_t y = (*(int16_t*) y_a) >> 6;
    
    uint8_t z_a[2] = {out_z_l, out_z_h};
    int16_t z = (*(int16_t*) z_a) >> 6;