树霉pi ioctl i2c读取 24c256,其它pi也行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#define ADDRESS 0x50
#define WRITECYCLE 5 //ms
#define PORT 1
int fd;
int iicwrite(char* buf, int addr, int start, int len)
{
struct i2c_msg msgs ;
char* buf0= malloc(len+2);
msgs.addr = addr;
msgs.flags = 0;
msgs.len = len+2;
buf0[0] = (start>>8)&0xff;
buf0[1] = start&0xff;
memcpy(buf0+2,buf,len);
msgs.buf = buf0;
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = &msgs;
rdwr.nmsgs = 1;
int res = ioctl(fd, I2C_RDWR, &rdwr);
usleep(WRITECYCLE*1000);
free(buf0);
return res;
}
int iicread(char* buf,int addr, int start, int len)
{
struct i2c_msg msgs[2] ;
char buf0[2];
msgs[0].addr = addr;
msgs[0].flags = 0;
msgs[0].len = 2;
buf0[0] = (start>>8)&0xff;
buf0[1] = start&0xff;
msgs[0].buf = buf0;
msgs[1].addr = addr;
msgs[1].flags = 1; // read
msgs[1].len = len;
msgs[1].buf = buf;
struct i2c_rdwr_ioctl_data rdwr;
rdwr.msgs = msgs;
rdwr.nmsgs = 2;
int res = ioctl(fd, I2C_RDWR, &rdwr);
return res;
}
int setup(int port, int addr) {
char fname[16];
snprintf(fname,sizeof(fname),"/dev/i2c-%d",port);
if((fd=open(fname, O_RDWR))<0)
exit(1);
int res = ioctl(fd,I2C_SLAVE_FORCE,addr);
return res;
}
int main(){
int plen = 94; //printable ascii
char astr[plen+1];
unsigned char i;
for( i = 0; i < 95; i++)
astr[i] = i+' ';
int addr = ADDRESS;
setup(PORT,addr);
iicwrite( astr, addr, 0, plen);
memset(astr,0,plen);
iicread( astr, addr, 0, plen);
astr[plen+1] = 0;
printf("%s\n",astr+1);
fclose(fd);
}
PORT 端口号 /dev/i2c-1 默认1
24c256 write cycle time 5 ms
a0 a1 a2 接地 地址 0x50
两个问题
一 i2c 不通优先检查杜邦线,浪费很长时间,才发现是线的事。
二 at24c256 write cycle time max 5毫秒, 写后延时5ms 再读。