如何读取 12 位的 i2c lis3dh 寄存器值?

How to read i2c lis3dh register value with 12 bits?

我需要读取 LIS3DH 加速度计的 i2c 寄存器值(12 位)。我为此开发了这段代码,但我总是得到重复的值。

void read_register(int filedesc,uint8_t register_address, uint16_t* register_value)
{
    uint8_t str[2] = {0};

    if (write(filedesc, &register_address, 1) == 1)
    {
        if (read(filedesc, str, 2) == 2)
        {
            *register_value = (((uint16_t)str[1])<<8) | ((uint16_t)str[0]);
           printf("register value = 0x%04X", *register_value)
        }
    }
    else
    {
        perror("error");
    }
}

当我执行我的程序时,我得到了重复的值,例如

寄存器值=0x3030

寄存器值=0x5D5D

我想使用此函数读取 x、y 和 z 的值。

在你的函数中添加一行:

register_address |= 0x80;

来自 LIS3DH 数据表:

... a 8-bit sub-address (SUB) is transmitted: the 7 LSb represent the actual register address while the MSB enables address auto increment. If the MSb of the SUB field is ‘1’, the SUB (register address) is automatically increased to allow multiple data read/write.

不设置MSB,就是一直读芯片中同一个寄存器,就是一个字节。换句话说,由于您不添加自动递增位,地址不会递增,并且读取的地址将始终是值的低位部分,因为高位部分在下一个寄存器中(高一个地址) .一件事是你也可以像这样一次读取3个寄存器(6字节),因为x,y,z寄存器是连续的。

此外,您可以直接执行 read(filedesc, register_value, 2),因为寄存器是小端(第一个是低端)。一次性使用 3 个寄存器也是如此,唯一的区别是您将 uint16_t[3] 作为参数传递,并读取 6 而不是 2.

故障肯定在别处,因为当我运行这个复制你的类型和动作的程序时,它运行得很好。

#include <stdio.h>

#define uint8_t unsigned char
#define uint16_t unsigned short

int main (int argc, char *argv[]) {
    uint8_t str[2] = { 0x12, 0x34 };
    uint16_t reg, *register_value = &reg;

    *register_value = (((uint16_t)str[1])<<8) | ((uint16_t)str[0]);
    printf("register value = 0x%04X", *register_value);
    return 0;
}

程序输出:

register value = 0x3412