I2C读取返回不正确的值

时间:2015-06-04 12:40:06

标签: c i2c ioctl

我试图像i2cget一样读取i2c值,但是在其中一个案例中它返回了错误的值。

i2cget -y 0 0x57 0x40返回0x57
i2cget -y 0 0x3b 0x09返回0x86

当我使用#define I2C_ADDR 0x57buffer[0] = 0x40运行我的程序时,我的程序会返回0x57

但是当我使用#define I2C_ADDR 0x3bbuffer[0] = 0x09运行我的程序时,我的程序会返回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, "\0", 1)                        = 1
close(3) 

1 个答案:

答案 0 :(得分:1)

strace i2cget我研究了0x720,发现它是I2C_SMBUS的值。然后,我在i2cget中找到了buildroot的源代码。

在C代码中没有使用它,但是使用了函数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;
}