I2C 读取 returns 不正确的值

I2C Read returns incorrect value

我正在尝试像使用 i2cget 一样读取 i2c 值,但在其中一种情况下它返回了错误的值。

i2cget -y 0 0x57 0x40 returns 0x57
i2cget -y 0 0x3b 0x09 returns 0x86

当我 运行 我的程序 #define I2C_ADDR 0x57buffer[0] = 0x40 我的程序 returns 0x57.

但是当我 运行 我的程序与 #define I2C_ADDR 0x3bbuffer[0] = 0x09 我的程序 returns 0x00.

这是我的代码:

// #define I2C_ADDR 0x57
#define I2C_ADDR 0x3b

// #define I2C_REG 0x40
#define I2C_REG 0x09

int main(int argc, char **argv) {

    char buffer[1];
    buffer[0] = I2C_REG;

    int fd;

    // Get i2c File Descriptor
    if((fd = open("/dev/i2c-0", O_RDWR)) >= 0){

        // Set i2c Block Address
        if((ioctl(fd, I2C_SLAVE, I2C_ADDR)) >= 0) {

            // Set i2c Register Address
            write(fd, buffer, 1);

            // Read data at Register into buffer
            read(fd, buffer, 1);

            // Close fd
            close(fd);

            // Print Result
            printf("0x%02x\n", buffer[0]);

        } else {
            // ioctl error
            printf("ioctl error: %s\n", strerror(errno));
        }
    } else {
        // file error
        printf("Error opening file: %s\n", strerror(errno));
    }

    return 0;
}

我 运行 strace i2cget -y 0x3b 0x09 和我的程序。这是一段输出,显示了 2 个读数的不同之处。

i2cget:

open("/dev/i2c-0", O_RDWR|O_LARGEFILE)  = 3
ioctl(3, 0x705, 0xbeae5bf8)             = 0
ioctl(3, 0x703, 0x3b)                   = 0
ioctl(3, 0x720, 0xbeae5b4c)             = 0
close(3)                                = 0

我的程序:

open("/dev/i2c-0", O_RDWR|O_LARGEFILE)  = 3
ioctl(3, 0x703, 0x3b)                   = 0
write(3, "\t", 1)                       = 1
read(3, "[=13=]", 1)                        = 1
close(3) 

i2cgetstrace查了0x720,发现是I2C_SMBUS的值。然后我在 buildroot.

中找到了 i2cget 的源代码

C 代码中没有使用 this,但使用了函数 i2c_smbus_read_byte_data。我将它添加到我的代码中并 运行 它,它不会 运行 由于函数未定义。我将 i2c-dev.h 文件从 buildroot 复制到我的文件夹并更改 #include 以包含本地文件和它 运行,并输出正确的数据。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "i2c-dev.h"

#define I2C_ADDR 0x3b
#define I2C_REG 0x09

// Prints Value of /dev/i2c-0 at Block 0x3b Register 0x09
int main(int argc, char **argv) {
    int fd, res;

    if ((fd = open("/dev/i2c-0", O_RDWR)) >= 0) {

        ioctl(fd, I2C_SLAVE, I2C_ADDR);

        res = i2c_smbus_read_byte_data(fd, I2C_REG);

        close(fd);

        printf("Value - 0x%02x\n", res);
    } else {
        printf("Error opening file: %s\n", strerror(errno));
    }

    return 0;
}