关于eeprom AT24C64数据写入问题

[复制链接]
10707|12
 楼主| kin0001 发表于 2013-9-20 22:03 | 显示全部楼层 |阅读模式
首次使用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
,原来是这样子的,英文不太好,所以下载了个中文的,但没有提到页写这项,感谢各位的回答 ...

搞电子,英文不好就别搞了(过四级不叫英语好,我也没过四级)。电子世界只有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
==================== ...

讲解的很细致
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

63

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部