Linux I2C应用编程操作流程
1)确定I2C设配器的设备文件节点
i2c适配器的设备节点是/dev/i2c-x,其中x是数字。由于适配器编号是动态分配的(和注册次序有关),可以使用i2ctools工具配置设备树节点注册进行查看
2)打开适配器对应的设备节点
当用户打开适配器设备节点的时候,Kernel中的i2c-dev代码为其建立一个i2c_client,但是这个i2c_client并不加到i2c_adapter的client链表当中。当用户关闭设备节点时,它自动被释放。
3) IOCTL控制
这个可以参考内核源码中的include/linux/i2c-dev.h文件。下面举例说明主要的IOCTL命令:
4) 使用I2C协议和设备进行通信
测试例子程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
//#define CHIP_ADDR 0x1a
#define I2C_DEV "/dev/i2c-2" //i2c_dev为i2c
#define PAGE_SIZE 1
static int iic_read(int fd, char buff[], int addr, int count)
{
int i,res;
if(write(fd,&addr,1)!=1) //将要操作的寄存器首地址发给从设备
return -1;
res=read(fd,buff,count);
printf("read %d byte at 0x%02x\n", res, addr);
for(i=0;i<res;i++){
printf("read %d data is :0x%02x\n",i,buff[i]);
}
return res;
}
static int iic_write(int fd, char buff[], int addr, int count)
{
int i,res;
static char sendbuffer[PAGE_SIZE+1];
memcpy(sendbuffer+1, buff, count);
sendbuffer[0]=addr; //将要操作的寄存器首地址赋给sendbuffer[0]
for(i=0; i<sizeof(sendbuffer); i++)
printf("wirte %d data is 0x%02x\n",i,sendbuffer[i]);
res=write(fd,sendbuffer,count+1);
printf("write %d byte at 0x%02x\n", res, addr);
return res;
}
int main(void){
int fd;
int res;
char ch;
char buf[50];
int regaddr,i,slaveaddr;
fd = open(I2C_DEV, O_RDWR);// I2C_DEV /dev/i2c-2
if(fd < 0){
printf("####i2c test device open failed####\n");
return (-1);
}else{
printf("### i2c test %s open success###\n",I2C_DEV);
}
printf("please input slave addr:");
scanf("%x",&slaveaddr);
printf("input slave addr is:0x%x\n",slaveaddr);
printf("please input reg addr:");
scanf("%x",®addr);
printf("input reg addr is:0x%x\n",regaddr);
getchar();
printf("#####usage####\n");
printf("input 0:to exit\n");
printf("input 1:read i2c test\n");
printf("input 2:write i2c test\n");
res = ioctl(fd,I2C_TENBIT,0); // 0 7bit;1 10bit
res = ioctl(fd,I2C_SLAVE_FORCE,slaveaddr);
while((ch=getchar())!='0'){
switch(ch){
case '1':
getchar();
printf("read i2c test\n");
usleep(1000);
res=iic_read(fd,buf,regaddr,1);
printf("%d bytes read success\n",res);
break;
case '2':
getchar();
buf[0]=0x01;
printf("write i2c test\n");
res=iic_write(fd,buf,regaddr,1);
printf("%d bytes write success\n",res);
break;
default:
printf("bad command\n");
break;
}
}
return 0;
}