Mar*_*ine 4 binary type-conversion raspberry-pi3
我正在用 C++ 和 Qt 对 Raspberry Pi 3 进行编程。我正在使用WiringPi库与 I2C 加速度计连接(我用它来比较倾斜角度值,但不测量角度)。
我需要确定一个加速度计读数是否大于或小于前一个读数或具有任意预设值。(我的机器上有一个手臂,我想将其设置为任意角度,然后让手臂移动到该角度或从该角度移动。)
加速度计以两个字节的二进制补码数据输出读数。数据为十二位左对齐。(我假设这意味着加速度计值的 4 个最高有效位位于高字节的左侧?)加速度计是 LIS3DH。
我正在将两个字节作为 2 个整数值读入程序中,但我正在努力将数据转换为有用的信息。
WiringPi I2C 库仅返回整数。
我可能需要将十进制读数转换为二进制,将两个字节的二进制补码左对齐二进制数据转换为十二位右对齐常规二进制数据。
我正在寻找有关如何完成此任务的建议,以及是否有比上面列出的路径更简单的方法来完成此任务。
编辑:
void main(void)
{
int acc_l = 0, acc_h = 0;
acc_l = read_output_register_lo;
acc_h = read_output_register_hi;
/*
How do I convert acc_l and acc_h to binary?
Do I need to shift acc_h 4 bits to the right?
How do I concatenate acc_h and acc_l into a 12 bit binary number?
How do I convert 12 bit twos compliment binary into regular binary?
Is this the correct process to follow?
Is there an easier way to do this?
*/
}
Run Code Online (Sandbox Code Playgroud)
编辑:非常感谢罗马。我提出了相同的基本概念,但似乎我将两个寄存器颠倒了。再次感谢你。
我也在使用 LIS3DH,经过几个小时的阅读和尝试,我终于弄清楚了。虽然我的代码是针对AVR单片机的,但是方法还是一样的。
\n\n加速度计将其读数显示为左对齐16 位值,分为每个轴的 2 字节寄存器:OUT_X_L, OUT_X_H, OUT_Y_L, OUT_Y_H, OUT_Z_L, OUT_Z_H。左对齐的意思是:所有的值位都左移。有多少位?这取决于你的精确度。
假设您使用 10 位精度(默认值),并且您想要读取 X 轴值,那么您的OUT_X_H和OUT_X_L寄存器将如下所示:
\xe2\x95\x94\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa6\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x97\n\xe2\x95\x91 \xe2\x95\x91 OUT_X_H \xe2\x95\x91 OUT_X_L \xe2\x95\x91\n\xe2\x95\xa0\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xac\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa3\n\xe2\x95\x91 Content \xe2\x95\x91 xxxx xxxx \xe2\x95\x91 xx00 0000 \xe2\x95\x91\n\xe2\x95\x9a\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa9\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x9d\nRun Code Online (Sandbox Code Playgroud)\n\nx - 是您想要的值,0 只是零。由于精度为 10 位,因此 6 个较低有效位将始终为零。
\n\n为什么有人想要发送这样的数据?原因很简单 - 如果你不关心精度,你可以只读取高位寄存器并将其存储为 8 位整数(int8_t )。由于左对齐,更多的最高有效位被保留,并且低寄存器中仅丢失 2 位。另一方面,右对齐更容易操作,但如果不读取整个 16 位值,就会丢失大量信息。
现在,如果您想将此值转换为“正常”值(右对齐),则需要将其存储为 16 位整数 ( int16_t)。计算机将有符号整数保存为二进制补码,LIS3DH 也是如此,这意味着存储在该int16_t变量中的值将具有正确的符号。您要做的最后一个操作是将该值右移 6(对于 10 位精度),瞧!
我编写了两种转换方法,一种是基于典型的位操作,第二种是指针转换自杀。
\n\nint16_t x = out_x_h; // 1.\nx <<= 8; // 1.\nx |= out_x_l; // 2.\nx >>= 6; // 3.\n\nint16_t y = out_y_h;\ny <<= 8;\ny |= out_y_l;\ny >>= 6;\n\nint16_t z = out_z_h;\nz <<= 8;\nz |= out_z_l;\nz >>= 6;\nRun Code Online (Sandbox Code Playgroud)\n\n对于每个轴:
\n\nuint8_t x_a[2] = {out_x_l, out_x_h}; // 1.\nint16_t x = (*(int16_t*) x_a) >> 6; // 2.\n\nuint8_t y_a[2] = {out_y_l, out_y_h};\nint16_t y = (*(int16_t*) y_a) >> 6;\n\nuint8_t z_a[2] = {out_z_l, out_z_h};\nint16_t z = (*(int16_t*) z_a) >> 6;\nRun Code Online (Sandbox Code Playgroud)\n\n对于每个轴:
\n\nuint8_t到int16_t指针,因此指向字节数组的指针被视为指向一个 16 位整数的指针,取消引用它,并右移 6。| 归档时间: |
|
| 查看次数: |
5501 次 |
| 最近记录: |