imx6ull的i2c应用开发
1、无需配置设备树
2、开启内核i2c控制器
make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
Device Drivers —>
<> I2C support —>
<> I2C device interface
3、开发板上运行 i2cdetect -a 0 查看I2C-0下的设备
ap3216c 器件地址 0x1e (/dev/I2c-0)
4、代码:ap3216c.c
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <unistd.h>
#include <fcntl.h>
#define AP3216C_ADDR 0x1e
static int fd;
int ap3216c_init(void)
{
char buf[100];
//int err;
struct i2c_rdwr_ioctl_data rdwr;
struct i2c_msg msgs[1];
int nmsgs_sent;
fd=open("/dev/i2c-0",O_RDWR);//打开设备,读写
if(fd<0)
{
printf("can not open i2c bus\n");
return 0;
}
msgs[0].addr = AP3216C_ADDR; //ap3216c的地址
msgs[0].flags = 0; // 写数据:0,读数据:1
msgs[0].len = 2; //buf长度这里为2
msgs[0].buf = buf;
buf[0] = 0; //第一字节为寄存器地址
buf[1] = 4; //第二字节是数据
rdwr.msgs = msgs;
rdwr.nmsgs = 1;//msgs的数量
nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
if (nmsgs_sent < 0 )
{
printf("can not reset ap3216c\n");
printf("nmsgs_sent :%d\n",nmsgs_sent);
return -1; /* err */
}
/* enable ap3216c */
msgs[0].addr = AP3216C_ADDR;
msgs[0].flags = 0; /* 写数据:0,读数据:1 */
msgs[0].len = 2;
msgs[0].buf = buf;
buf[0] = 0; //第一字节为寄存器地址
buf[1] = 3; //第二字节是数据
rdwr.msgs = msgs;
rdwr.nmsgs = 1;
nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);//调用驱动层代码,将数据传递
if (nmsgs_sent < 0 )
{
printf("can not enable ap3216c\n");
return -1; /* err */
}
return 0;
}
/*读取光照数据*/
int ap3216c_read_light(void)
{
struct i2c_rdwr_ioctl_data rdwr;
struct i2c_msg msgs[2];
int nmsgs_sent;
char buf_tx[1];
char buf_rx[2];
int light;
msgs[0].addr=AP3216C_ADDR;
msgs[0].flags=0;//写数据
msgs[0].len=1;
msgs[0].buf=buf_tx;
buf_tx[0]=0xc; //寄存器地址
msgs[1].addr = AP3216C_ADDR;
msgs[1].flags = I2C_M_RD; /* 读数据:1, I2C_M_RD */
msgs[1].len = 2; //读取长度2字节
msgs[1].buf = buf_rx;
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);//调用驱动层代码
if (nmsgs_sent < 0)
{
printf("can not read ap3216c light\n");
return -1; /* err */
}
light = (buf_rx[1]<<8) | buf_rx[0];
return light;
}
/*读取距离值*/
int ap3216c_read_distance(void)
{
struct i2c_rdwr_ioctl_data rdwr;
struct i2c_msg msgs[2];
int nmsgs_sent;
char buf_tx[1];
char buf_rx[2];
int distance;
/* 发送寄存器地址 */
msgs[0].addr = AP3216C_ADDR;
msgs[0].flags = 0; /* 写:0*/
msgs[0].len = 1;
msgs[0].buf = buf_tx;
buf_tx[0] = 0xe; //寄存器地址
msgs[1].addr = AP3216C_ADDR;
msgs[1].flags = I2C_M_RD; /* read:1, 读:I2C_M_RD */
msgs[1].len = 2;
msgs[1].buf = buf_rx;
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
nmsgs_sent = ioctl(fd, I2C_RDWR, &rdwr);
if (nmsgs_sent < 0 )
{
printf("can not read ap3216c light\n");
return -1; /* err */
}
distance = ((buf_rx[1] & 0x3F)<<4) | (buf_rx[0] & 0xf);
return distance;
}
int main(int argc, char **argv)
{
int err;
int light, distance;
int cnt = 0;
err = ap3216c_init();
if (err)
{
printf("ap3216c_init err : %d\n", err);
}
while (1)
{
light = ap3216c_read_light();
distance = ap3216c_read_distance();
printf("%03d: light = %d, distance = %d\n", cnt, light, distance);
cnt++;
sleep(2);
}
return 0;
}
5、编译
arm-linux-gnueabihf-gcc -o ap3216c ap3216c.c
./ap3216c