我用的是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总线
}
AT24C512是8位的存储器, 它的16位地址并不是常规16位存储器的地址.
你注意看其规格书的第3页: Memory Organization的描述. 它的16位地址包含2个部分,高9位是页地址, 低7位是页内偏址. 共512页,每页存储128字节.
在以单个字节写的时候,地址是两个8位数。还有就是我在程序里,写的地址跟读的地址是一样的,应该说就是页地址一样,页内地址也一样,那为什么数据就变以了。
这个程序之前用没问题,就在这次使用就出来这个问题了,说明:硬件一样,器件是同一批货,代码也是之前的代码,没修改过。太奇怪了,找了好久没找到原因。
问题解决了,换了新的AT24C512芯片就好了。应该是器件放置时间长了,就出问题了。
刚开始测试出问题的是放置了两年的器件,现在拿来用,就不能用16位地址进行读写,只能用8位
新的就没问题