首页 > 解决方案 > i2c 读取 /dev/i2c 上的寄存器

问题描述

我编写了一个小型测试程序,它读取 LSM6DSO 芯片上的温度寄存器,并在读取 /dev/i2c(IOCTL 调用)后正确显示温度,但在读取芯片时iio_generic_buffer()(依赖于 sysfs 文件系统)正确更新寄存器并在每次读取时返回略有不同的值,我的程序会一遍又一遍地显示相同的值。

所以问题是:我错过了什么?为什么寄存器不使用下一个温度进行自我更新?

int main()
{
...
   for (i = 0; i <= 100; i++) {
        i2c_read_1_byte(0x6a, 0xf, result); // reading 1 byte of register 0xf (WHO_AM_I)

        printf("Read %#02X\n", result[0]);

        i2c_read_1_byte(0x6a, 0x20, result);
        templ = result[0];
        i2c_read_1_byte(0x6a, 0x21, result);
        temph = result[0];

        printf("Read temph %#02X\n", temph);
        printf("Read templ %#02X\n", templ);

        res = (((unsigned short)temph << 8) & 0xFF00) | templ;

        printf("res: 0x%x\n", res);
}

int i2c_read_1_byte(unsigned char slave_addr, unsigned char reg, unsigned char *result)
{
    unsigned char outbuf[1], inbuf[1];
    struct i2c_msg msgs[2];
    struct i2c_rdwr_ioctl_data msgset[1];

    msgs[0].addr = slave_addr;
    msgs[0].flags = 0;
    msgs[0].len = 1;
    msgs[0].buf = outbuf;

    msgs[1].addr = slave_addr;
    msgs[1].flags = I2C_M_RD | I2C_M_STOP;
    msgs[1].len = 1;
    msgs[1].buf = inbuf;

    msgset[0].msgs = msgs;
    msgset[0].nmsgs = 2;

    outbuf[0] = reg;

    inbuf[0] = 0;

    *result = 0;
    if (ioctl(i2c_fd, I2C_RDWR, &msgset) < 0) {
        perror("ioctl(I2C_RDWR) in i2c_read");
        return -1;
    }

    *result = inbuf[0];
    return 0;
}

标签: linuxembeddedi2c

解决方案


解决了,是一个时序问题,所以从 usleep 开始并结束轮询 DTA_RDY 寄存器......


推荐阅读