在Linux上使用I2C进行读取/写入

问题描述:

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

当我试着写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上有没有针对FM24CL64-GTR的FRAM驱动程序,API是什么?任何链接都会有帮助。

+0

您应该使用exit()(不带前导下划线),而不是_exit()。 _exit()没有正确关闭libc。 – 2009-02-02 22:02:37

+0

谢谢,这只是硬件启动测试代码,但仍感谢您的反馈。 – TheSeeker 2009-02-02 23:40:46

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

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

我没有使用该特定器件的经验,但根据我们的经验,许多I2C器件有“怪癖”,需要解决方法,通常高于驱动器级别。

我们还使用Linux(CELinux)和I2C设备驱动程序以及Linux。但是我们的应用程序代码还有一个非平凡的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 =重复启动)。因此,为您节省了一个多余的暂时性的问题。

不,它不同于很多时间,但如果不需要的话,为什么它失去...

只是我的2克拉。

Best rgds,

你有一些错误!

ic的地址是Ax(十六进制),x可以是任何内容,但是4个高位应该是A=1010 !!!