在Linux上使用I2C进行读写

我试图读取/写入通过地址为0b 1010 011的I2C总线连接的FM24CL64-GTR FRAM芯片。

当我试图写3个字节(数据地址2个字节,+数据一个字节)时,我得到一个内核消息( [12406.360000] i2c-adapter i2c-0: sendbytes: NAK bailout. ),以及写回车!= 3.请参阅下面的代码:

 #include <linux/i2c-dev.h> #include <fcntl.h> #include <unistd.h> #include <stdint.h> int file; char filename[20]; int addr = 0x53; // 0b1010011; /* The I2C address */ uint16_t dataAddr = 0x1234; uint8_t val = 0x5c; uint8_t buf[3]; sprintf(filename,"/dev/i2c-%d",0); if ((file = open(filename,O_RDWR)) < 0) exit(1); if (ioctl(file,I2C_SLAVE,addr) < 0) exit(2); buf[0] = dataAddr >> 8; buf[1] = dataAddr & 0xff; buf[2] = val; if (write(file, buf, 3) != 3) exit(3); ... 

但是,当我写2个字节,然后写另一个字节,我没有得到内核错误,但是当试图从FRAM读取,我总是回来0.这里是从FRAM读取的代码:

 uint8_t val; if ((file = open(filename,O_RDWR)) < 0) exit(1); if (ioctl(file,I2C_SLAVE,addr) < 0) exit(2); if (write(file, &dataAddr, 2) != 2) { exit(3); if (read(file, &val, 1) != 1) { exit(3); 

没有一个函数返回一个错误值,我也试过:

 #include <linux/i2c.h> struct i2c_rdwr_ioctl_data work_queue; struct i2c_msg msg[2]; uint8_t ret; work_queue.nmsgs = 2; work_queue.msgs = msg; work_queue.msgs[0].addr = addr; work_queue.msgs[0].len = 2; work_queue.msgs[0].flags = 0; work_queue.msgs[0].buf = &dataAddr; work_queue.msgs[1].addr = addr; work_queue.msgs[1].len = 1; work_queue.msgs[1].flags = I2C_M_RD; work_queue.msgs[1].buf = &ret; if (ioctl(file,I2C_RDWR,&work_queue) < 0) exit(3); 

这也成功,但总是返回0.这是否表示硬件问题,或者我做错了什么?

在Linux上是否有通过I2C的FM24CL64-GTR的FRAM驱动程序,API会是什么? 任何链接都会有所帮助。

Solutions Collecting From Web of "在Linux上使用I2C进行读写"

NAK是一个很大的提示:WriteProtect引脚被外部上拉,并且必须被驱动到地,然后单次写入数据字节之后的地址是成功的(第一个代码段)。

读取地址可以先写出(使用write()),然后从该地址开始读取连续的数据。

我没有这方面的经验,但根据我们的经验,许多I2C器件有“怪癖”,需要一个解决方案,通常高于驱动器级别。

我们还使用Linux(CELinux)和一个I2C设备驱动程序。 但是我们的应用程序代码也有一个非平凡的I2C模块,它包含了处理所有我们所经历的各种设备的所有解决方案。

另外,在处理I2C问题时,我经常发现我需要重新熟悉源规范:

http://www.nxp.com/acrobat_download/literature/9398/39340011.pdf

以及使用像样的示波器。

祝你好运,

以上链接已经死了,这里有一些其他的链接:

http://www.nxp.com/documents/user_manual/UM10204.pdf ,当然还有维基百科: http : //en.wikipedia.org/wiki/I%C2%B2C

请注意,使用struct i2c_rdwr_ioctl_datastruct i2c_msg (也就是您所提供的最后一个代码部分)的方法比其他方法更高效,因为使用该方法可以执行I2c的重复启动功能。

这意味着您避免了STA-WRITE-STO -> STA-READ-<data>...-STO转换,因为您的通信将变为STA-WRITE-RS-READ-<data>...STORS =重复开始)。 所以,为您节省了一个冗余的STO-STA瞬变。

这并不是说它在时间上有很大的不同,但是如果不需要的话,为什么还要这么做呢?

只是我2克拉。

最好的rgds,

你有一些错误!

ic的地址是十六进制的Axx可以是任何东西,但是4个高位应该是A=1010