Linux环境下I2C应用程序编写

本文介绍了如何在Linux系统中使用i2c-tools工具包来探测和操作I2C总线,包括i2cdetect命令的使用、数据的写入和读取。此外,还展示了通过编程在用户空间进行I2C读写操作的方法,包括read/write方式和ioctl方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文介绍Linux环境下,对I2C设备进行操作。

在对I2C总线进行操作时,可采用i2c-tools对I2C进行查看及操作,待通过工具可对I2C进行操作后,再编写程序进行操作。

1.i2c-tools的使用

1)安装

sudo apt install i2c-tools

2)查询

i2cdetect -l

执行结果如下,可以看到所有的i2c总线。

 单独查看第1组I2C总线下挂接的设备,可采用:

i2cdetect -y 1

执行结果如下,可以看到i2c-1总线下的设备,如0x36(7 bit I2C地址)。

3)写数据

i2ctransfer -f -y 1 w3@0x36 0x01 0x00 0x01

向0x0100写入0x01,这里总计写入了3个字节的数据(w3)。

4)读数据

i2ctransfer -f -y 1 w2@0x36 0x01 0x00 r1

读取0x0100处数据,按I2C协议,先写入寄存器地址(w2),再进行读取(r1)。

某些芯片仅支持读(不用设置寄存器值,读取默认寄存器)操作,可以:

i2ctransfer -f -y r1@0x36

2.用户空间下的读写操作

1)read,write方式

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
 
int main(int argc, char **argv)
{
    int fd;
    unsigned char buf[16];
 
    fd = open("/dev/i2c-1", O_RDWR);
    if (fd == -1) {
        printf(“open device failed!\n”);
        return -1;
    }

    ioctl(fd, I2C_SLAVE, 0x36); //slave address(7 bit)
    ioctl(fd, I2C_TIMEOUT, 1); //timeout
    ioctl(fd, I2C_RETRIES, 1); //try count
 
    //write data to i2c-1
    buf[0] = 0x01;
    buf[1] = 0x00;
    buf[2] = 0x01; 
    write(fd, &buf[0], 3);

    //read data from i2c-1
    buf[0] = 0x01;
    buf[1] = 0x00;
    write(fd, &buf[0], 2);  //write register address first
    buf[2] = 0x00;
    read(fd, &buf[2], 1);  //read data

    printf("%d\n", buf[2]);

    close(fd);
 
    return 0;
}

2)ioctl方式

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
 
int main(int argc, char **argv)
{
    struct i2c_rdwr_ioctl_data i2c_queue;
    int fd;
    unsigned char buf[3];
    int ret;
 
    fd = open("/dev/i2c-1", O_RDWR);
    if (fd == -1) {
        printf(“open device failed!\n”);
        return -1;
    }
 
    i2c_queue.nmsgs = 2;
    i2c_queue.msgs = (struct i2c_msgs *)malloc(i2c_queue.nmsgs * sizeof(struct i2c_msg));
    if (i2c_queue.msgs == NULL) {
        printf(“memory alloc error!\n”);
        close(fd);
        return 1;
    }
 
    ioctl(fd, I2C_TIMEOUT, 2); //timeout
    ioctl(fd, I2C_RETRIES, 1); //try count

    //write data to i2c-1
    i2c_queue.nmsgs = 1;
    (i2c_queue.msgs[0]).addr = 0x36; //slave address(7 bit)
    (i2c_queue.msgs[0]).len = 3;
    (i2c_queue.msgs[0]).flags = 0;
    (i2c_queue.msgs[0]).buf = buf; //(unsigned char *)malloc(3)
    (i2c_queue.msgs[0]).buf[0] = 0x01;
    (i2c_queue.msgs[0]).buf[1] = 0x00;
    (i2c_queue.msgs[0]).buf[2] = 0x01;
    ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_queue);
    if (ret < 0)
        printf(“i2c write failed!\n”);

    //read data from i2c-1
    i2c_queue.nmsgs = 2;
    (i2c_queue.msgs[0]).addr = 0x36; //slave address(7 bit)
    (i2c_queue.msgs[0]).len = 2;
    (i2c_queue.msgs[0]).flags = 0;
    (i2c_queue.msgs[0]).buf = buf;
    (i2c_queue.msgs[0]).buf[0] = 0x01;
    (i2c_queue.msgs[0]).buf[1] = 0x00;

    (i2c_queue.msgs[1]).addr = 0x36;
    (i2c_queue.msgs[1]).len = 1;
    (i2c_queue.msgs[1]).flags = I2C_M_RD;
    (i2c_queue.msgs[1]).buf = &buf[2]; //(unsigned char *)malloc(1)
    (i2c_queue.msgs[1]).buf[0] = 0;
    ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_queue);

    if (ret < 0)
        printf(“i2c read failed!\n”);
    else
        printf(“%02x\n”, buf[2]);

    close(fd);
 
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值