kin0001 发表于 2013-9-20 22:03

关于eeprom AT24C64数据写入问题

首次使用AT24C64的TWI总线读取数据,遇到一个问题,想请大家帮忙解答一下;
mcu:ATmega324pa;
eeprom:at24c64;
举个例子:
向eep24C64连续写入20个数据;然后读取这20个数据;比如写入数据为A1A2A3A4A5B1B2B3B4B5
如果首地址为0x0080的话,读去出来的数据是对的;
如果首地址为0x0090的话,读出来的数据只有16个数据是对的(16-0=16,0x00A0地址后的数据不正确

如果首地址为0x0084的话,读出来的数据也是对的;
如果首地址为0x0094的话,读出来的术只有12个数据是对的(16-4=12;

后发现是数据写入出现了问题
总结就是:
如果低八位地址的高4位为偶数,20个数据写入都正常;
如果低八位地址的高4位为奇数,20个数据部分写入不正常;

另外,我的程序是没有对TWI状态进行检查的,不知道这样做会不会有影响
以下是源程序:

void TWIStartFun(void)                                             //启动
{
   TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
   while(!(TWCR&(1<<TWINT)))
      continue;
}
void TWIWriteByteFun(unsigned char TWIData)            //写操作
{
    TWDR=TWIData;
    TWCR=(1<<TWINT)|(1<<TWEN);
    while(!(TWCR&(1<<TWINT)))
      continue;
}
unsigned char TWIReadByteFun(unsigned char N_ACK)//读操作
{
    TWCR=N_ACK;
    while(!(TWCR&(1<<TWINT)))
      continue;
    return(TWDR);
}

//写入N字节数据
void WriteNByteFun(unsigned char SLA_W,unsigned int Address,unsigned char DataNum,unsigned char *TWIDataPoi)
{
    TWIStartFun();
    TWIWriteByteFun(SLA_W);                                           //器件写地址
    if(SLA_W!=PCFSLA_W)
      TWIWriteByteFun(Address>>8);                               //器件地址高8位(eep24c64)
    TWIWriteByteFun(Address);                                       //器件地址
    for(;DataNum!=0x00;DataNum--)
      TWIWriteByteFun(*TWIDataPoi++);
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);         //结束
    if(SLA_W!=PCFSLA_W)
}

//读N字节数据
void ReadNByteFun(unsigned char SLA_R,unsigned int Address,unsigned char DataNum,unsigned char *TWIDataPoi)
{
    TWIStartFun();
    TWIWriteByteFun(SLA_R-1);                                    //器件写地址
    if(SLA_R!=PCFSLA_R)
      TWIWriteByteFun(Address>>8);                            //地址高8位
    TWIWriteByteFun(Address);                                    //地址低8位
    TWIStartFun();
    TWIWriteByteFun(SLA_R);                                        //器件读地址
    if(DataNum>0x01)
    {
      do
      {
             *TWIDataPoi++=TWIReadByteFun((1<<TWINT)|(1<<TWEN)|(1<<TWEA));
         }while(--DataNum>0x01);
    }
    *TWIDataPoi=TWIReadByteFun((1<<TWINT)|(1<<TWEN)); //接收最后一个数据
   TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}




lyjian 发表于 2013-9-20 22:29

你没搞懂页写的要求。
自己认真看看规格书。

linqing171 发表于 2013-9-21 07:59

看手册,EEPROM里面是按页存储的。
EEPROM的写入时间很长,所以有个缓存,可以保存最多一页的数据。
你是跨页了,就回环了。
从0x94写16个,会写入0x94 0x95 ... 0x9F , 0x80 ,0x81 ,0x82, 0x83 地址。业内回环。
仔细看一下datasheet

NE5532 发表于 2013-9-21 08:35

亲,E2要分页的,搞硬件要先看数据手册,别瞎整。

lzqxs89 发表于 2013-9-21 08:55

数据手册虽然很麻烦但是确实很重要哦!

lirunze 发表于 2013-9-21 09:11

同意楼上

kin0001 发表于 2013-9-21 09:29

,原来是这样子的,英文不太好,所以下载了个中文的,但没有提到页写这项,感谢各位的回答

NE5532 发表于 2013-9-21 10:03

kin0001 发表于 2013-9-21 09:29 static/image/common/back.gif
,原来是这样子的,英文不太好,所以下载了个中文的,但没有提到页写这项,感谢各位的回答 ...

搞电子,英文不好就别搞了(过四级不叫英语好,我也没过四级)。电子世界只有2种语言:英语和日语,中文的没有!

kin0001 发表于 2013-10-2 20:27

这几天太忙了,忘结贴了,分就给第一位吧

zxm19820916 发表于 2016-8-22 22:42

我用stm32访问at24c64,也碰到一个问题,看来是和地址有关,datasheet没有仔细看。晕。

3htech 发表于 2016-8-23 10:08

本帖最后由 3htech 于 2016-8-23 10:15 编辑

可以参考一下。这套代码是比较老的了。
https://bbs.21ic.com/icview-370014-1-1.html
=====================================

下面是最新的代码,不依赖单片机类型,移植方便。




datouyuan 发表于 2016-8-24 17:56

3htech 发表于 2016-8-23 10:08
可以参考一下。这套代码是比较老的了。
https://bbs.21ic.com/icview-370014-1-1.html
==================== ...

看了下你的帖子,不错.

18555213691 发表于 2022-5-6 16:45

3htech 发表于 2016-8-23 10:08
可以参考一下。这套代码是比较老的了。
https://bbs.21ic.com/icview-370014-1-1.html
==================== ...

讲解的很细致
页: [1]
查看完整版本: 关于eeprom AT24C64数据写入问题