读写AT24C512的问题

需要移植AT24C512的驱动,做了一下几种实验:

1.利用内核自带的驱动,内核driver/misc下面的at.c就包含了ATMEL系列的EEPROM的驱动,只需要在BROAD_INFO改下名字。然后要选中menuconfig下的misc下的eeprom选项,最后重新烧录后,就能在板子/sys/bus/i2c/device/0-0050/下看到eeprom节点,对他进行读写就可以了。但是这不是我想要的


2.移植了i2c-tools-3.1.0.tar.bz2,原以为这个能很方便的操作I2C器件,结果令我大失所望,i2cset一个值,i2cget出来的却不对,不知是何缘故,故放弃了。


3.看来还是要写驱动了,我将板子上的AT24C512换成了AT24C02,取消第一项中打开的项目,重新烧录内核。 在i2c_prob函数中添加了测试代码,即写一个寄存器,然后读它的值,insmod at24c02.ko后发现能正确读写了。


4.将AT24C02换成AT24C512,修改刚刚OK的驱动为AT24C512,修改内核BROAD_INFO,烧录,再insmod at24c512.KO 却不能正确读写了。原来关键是AT24C02的内部地址是1字节的,而AT24C512的内部地址是2字节的,就是在发送地址这块出问题了,所以不能正确读取数据。

下面是读写AT24C02的正确方法:

static int i2c_read_bytes(struct i2c_client *client, unsigned char *buf, int len)  
{  
    struct i2c_msg msgs[2];  
    int ret=-1;  
    //发送写地址  
    msgs[0].flags=!I2C_M_RD;//写消息  
    msgs[0].addr=client->addr;  
    msgs[0].len=1;  
    msgs[0].buf=&buf[0];  
    //接收数据  
    msgs[1].flags=I2C_M_RD;//读消息  
    msgs[1].addr=client->addr;  
    msgs[1].len=len-1;  
    msgs[1].buf=&buf[1];  
      
    ret=i2c_transfer(client->adapter,msgs, 2);
    return ret;  
}  
static int i2c_write_bytes(struct i2c_client *client,unsigned char *data,int len)
{
    struct i2c_msg msg;
    int ret=-1;
    
    msg.flags=!I2C_M_RD;
    msg.addr=client->addr;
    msg.len=len;
    msg.buf=data; 
          
    ret=i2c_transfer(client->adapter,&msg, 1);
    return ret;
}

至于如何解决AT24C512的读写问题,进行中..............

已标记关键词 清除标记
我用的是AT24C512来存储数据,但写地址的时候,写完16位的地址,然后再写一个8位数据; 在读出来的时候,读到的是高8位地址所指向的地址的数据,且数据等于地址的低8位,怎么也读不到16位地址所指向地址的数据。 //向指定地址写一个字节数据 Write_IIC(0x00,0x00,0x10); //向0x0000地址写数据0x10 Delay(5); Write_IIC(0x01,0x01,0x11); //向0x0101地址写数据0x11 Delay(5); Write_IIC(0x02,0x02,0x12); //向0x0202地址写数据0x12 Delay(5); Write_IIC(0x03,0x03,0x13); //向0x0303地址写数据0x13 Delay(5); Write_IIC(0x04,0x04,0x14); //向0x0404地址写数据0x14 Delay(5); //读指定地址的数据 Send_Data(Read_ICC(0x00,0x00)); //读0x0000地址的数据 Delay(1); Send_Data(Read_ICC(0x01,0x01)); //读0x0101地址的数据 Delay(1); Send_Data(Read_ICC(0x02,0x02)); //读0x0202地址的数据 Delay(1); Send_Data(Read_ICC(0x03,0x03)); //读0x0303地址的数据 Delay(1); Send_Data(Read_ICC(0x04,0x04)); //读0x0404地址的数据 Delay(1); 我是从串口接收数据,读出来的数据为: 01 02 03 04 14 证明只有最后一次写,才把0x14写到0x0404里面;或者最后一次是往地址0x04写了一次0x04,然后再写0x14,0x14把0x04覆盖了。 第一次往0x0000写0x10不成功,第二次把地址的低8位0x01写到高8位地址0x01里去了,第三次,第四次与第二次一样。 为什么会这样 uchar Read_ICC(uchar ADD_H,uchar ADD_L) { uchar dat; I2C_Start(); Send_Byte(0xa0); //发器件地址,并通知准备发送地址 Response(); //应答 Send_Byte(ADD_H); //发器件内部存储器地址高位 Response(); //应答 Send_Byte(ADD_L); //发器件内部存储器地址低位 Response(); //应答 I2C_Start(); Send_Byte(0xa1); //发器件地址,并通知准备读取数据 Response(); //应答 dat=Rcv_Byte(); //读取数据 I2C_Stop(); //停止I2C总线 return (dat); } void Write_ICC(uchar ADD_H,uchar ADD_L,uchar dat) { I2C_Start(); Send_Byte(0xa0); //发器件地址,并通知准备发送地址,要对应芯片地址 Response(); //应答 Send_Byte(ADD_H); //发器件内部存储器地址高位 Response(); //应答 Send_Byte(ADD_L); //发器件内部存储器地址低位 Response(); //应答 Send_Byte(dat); //写入数据 Response(); //应答 I2C_Stop(); //停止I2C总线 }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页