Linux环境下I2C应用程序编写

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

本文介绍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;
}

要模拟Linux I2C驱动,我们需要理解I2C协议和Linux驱动框架的基本原理。 I2C(Inter-Integrated Circuit)是一种串行通信协议,允许多个器件通过共享的两根线(SDA和SCL)进行通信。在Linux中,I2C驱动负责管理I2C总线上的设备与内核的通信。 首先,我们需要创建一个虚拟I2C设备。可以使用I2C-dev驱动模块来创建一个模拟的I2C设备节点文件。这可以通过在终端中运行“modprobe i2c-dev”命令来加载模块。 然后,我们需要编写一个I2C驱动程序,它需要遵循Linux的驱动模型。驱动程序需要实现与I2C设备通信的函数,如读取和写入数据、发送和接收命令等。我们可以使用ioctl系统调用来实现这些操作。 另外,我们还需要在Linux的设备树(Device Tree)中添加对虚拟I2C设备的描述。这可以通过编辑设备树文件(如.dts或.dtsi)来完成。设备树会告诉内核如何初始化和配置I2C设备。 最后,我们需要编译和加载驱动程序。可以使用交叉编译工具链来编译驱动程序,并将其加载到Linux系统中。编译和加载驱动程序的具体步骤可以根据具体的开发环境和目标平台来进行配置和调整。 通过以上步骤,我们就可以在Linux系统上模拟一个I2C驱动。这样可以方便地进行I2C设备的开发和调试,而无需实际的硬件设备。同时,这也为Linux内核提供了一个通用的I2C接口,可以方便地与各种I2C设备进行通信。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值