linux应用层使用i2c

背景:linux应用层访问i2c出错,原因分析,i2c结构体数据错误,没有给i2c结构体分配内存,设备器件地址不对。


首先确定设备挂接在哪一条总线上,通过i2c-tool。

i2cdetect -l

或者

i2cdetect -y -r 3

i2c写函数:

unsigned char base_i2c_write(unsigned char device_addr, unsigned char *buff, int ByteNo)
{
    int fd, ret;
    const char *i2c_dev = "/dev/i2c-3";
    fd = open(i2c_dev, O_RDWR);
    struct i2c_rdwr_ioctl_data data;
    struct i2c_msg msgs_str[1];
    data.msgs = msgs_str;
    unsigned char sendbuf[255] = {0};
    printf("device_addr : %x\n",device_addr);
    fflush(stdout);
    //device_addr <<= 1;
    //printf("device_addr : %x\n",device_addr);
    fflush(stdout);
    data.nmsgs = 1;
    data.msgs[0].len = ByteNo;
    data.msgs[0].addr = device_addr;
    data.msgs[0].flags = 0;
    data.msgs[0].buf = sendbuf;
    memset(sendbuf, 0, 255);
    memcpy( sendbuf, buff, ByteNo);
    ioctl(fd,I2C_RDWR,(unsigned long)&data);
    printf("Write begin-> write data all :");
    fflush(stdout);
    for(int i=0; i

i2c读函数:

unsigned char base_i2c_read(unsigned char device_addr, unsigned char *buff, int ByteNo)
{
    int fd, ret;
    struct i2c_rdwr_ioctl_data i2c_data;
    const char      *i2c_dev = "/dev/i2c-3";
    fd = open(i2c_dev, O_RDWR);
    if (fd<0)
    {
        printf("not have /dev/i2c-0 t\r\n");
        fflush(stdout);
        return -1;
    }

    i2c_data.nmsgs = 1;
    i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs *sizeof(struct i2c_msg));
    if (i2c_data.msgs == NULL)
    {
        printf("malloc error");
        fflush(stdout);
        close(fd);
        return -1;
    }
    ioctl(fd, I2C_TIMEOUT, 1);
    ioctl(fd, I2C_RETRIES, 2);
    i2c_data.msgs[0].len = ByteNo;
    i2c_data.msgs[0].addr = device_addr;
    i2c_data.msgs[0].flags = 1;     // 0: write 1:read
    i2c_data.msgs[0].buf = buff;

    ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data);
    if (ret < 0)
    {
        printf("read data %x  error\r\n", device_addr);
        close(fd);
        free(i2c_data.msgs);
        return 1;
    }
    free(i2c_data.msgs);
    close(fd);

    int i;
    printf(" Begin print read data \n");
    for (i = 0; i < ByteNo; i++)
    {
        printf(" 0x%02x",buff[i]);
    }
    printf("\n");
    return 0;
}

注意事项:

  1. 从设备地址是芯片的真实地址,不是左移加上读写位那个虚地址。
  2. msg结构体必须分配空间,否则会出错。
  3. 读函数没有寄存器地址,如果需要先写寄存器再读,i2c_data.nmsgs 设为 2,msg[0]填充写的结果,msg[1]填写读的结构。

另外:

     如果需要动态传设备参数,修改fd的获得方式即可。

    int fd;
    struct i2c_rdwr_ioctl_data i2c_data;
    QString busName = QString("/dev/i2c-%1").arg(i2c_bus);
    fd = open(busName.toLatin1(), O_RDWR);
    if(fd < 0){
        printf("Don`t open the device...");
    }

 

你可能感兴趣的:(Linux应用层)