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

时间:2015-03-05 16:22:27

标签: c linux i2c

我需要读取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");
    }
}

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

注册值= 0x30 30

寄存器值= 0x5D 5D

我想阅读x,y和z的这个函数值。

2 个答案:

答案 0 :(得分:2)

在你的函数中添加一行:

register_address |= 0x80;

来自LIS3DH数据表:

  

...传输8位子地址(SUB):7 LSb   表示实际的寄存器地址,而MSB使能地址自动递增。如果   SUB字段的MSb为'1',SUB(寄存器地址)自动增加以允许   多个数据读/写。

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

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

答案 1 :(得分:0)

错误必须存在于其他地方,因为当我运行这个复制你的类型和动作的程序时,它完美地运作。

#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