找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6554|回复: 26
打印 上一主题 下一主题
收起左侧

单片机EEPROM 24C02 不能写入奇数,请高手解答

  [复制链接]
跳转到指定楼层
楼主
在向EEPROM 24c02 写数据时出现一个怪事,向一个地址写入偶数如:2、4、6...,可以写入,并且可以读出,但是写入奇数如:1、3、5...,则不能写入,读出的数还是以前的数据,不知为啥,请高手解答,谢谢!!!!

单片机程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit scl=P2^1;
sbit sda=P2^0;

void delay()
{;;}

void delay_ms(uint j)
{
        uint i;
        for(j;j>0;j--)
                for(i=110;i>0;i--);
}



void IIC_init()          //IIC初始化
{
        scl=1;
        sda=1;
}

void IIC_start()  //IIC开始信号
{
        scl=1;
        sda=1;
        delay();
        sda=0;
        delay();
}

void IIC_stop()                //IIC终止
{
        scl=1;
        sda=0;
        delay();
        sda=1;
        delay();
}

void IIC_check()                   //查看IIC器件是否应答
{
        scl=1;
        delay();
        while(sda);
        delay();  
        scl=0;        
}

void IIC_w_bite(uchar bite)                 //向IIC器件写1比特数据
{
        uchar i;
        for(i=8;i>0;i--)
        {
                scl=0;
                delay();
                bite=bite<<1;
                sda=CY;               
                delay();
                scl=1;
                delay();
                scl=0;
        }
}

uchar IIC_r_bite()                 //读取IIC器件1比特数据
{
        uchar i,dd;
        for(i=8;i>0;i--)
        {
                scl=1;
                delay();
                dd=dd<<1|sda;
                delay();
                scl=0;
                delay();                        
        }
        return dd;        
}

void main()
{
        IIC_init();
        IIC_start();
        IIC_w_bite(0xa0);                //寻址并发送给IIC器件准备写数据
        IIC_check();                                //应答
        IIC_w_bite(0x1);                //发送存储器存储地址
        IIC_check();
        IIC_w_bite(0x2);                //发送要给IIC器写入的数据
        IIC_check();
        IIC_stop();

        delay_ms(5);

        IIC_start();
        IIC_w_bite(0xa0);          //寻址并发送给IIC器件准备写数据
        IIC_check();                          //应答
        IIC_w_bite(0x1);          //发送存储器存储地址
        IIC_check();
        IIC_start();
        IIC_w_bite(0xa1);          //发送信息给IIC准备读数据
        IIC_check();
        P1=IIC_r_bite();          //读数据到P1口
        IIC_stop();
        while(1);
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2018-3-18 16:04 | 只看该作者
换一片24c02试试
回复

使用道具 举报

板凳
ID:293590 发表于 2018-3-18 16:11 | 只看该作者
24C02应该是很简单的的,建议楼主不要自己写,网上找一大堆例子
回复

使用道具 举报

地板
ID:284522 发表于 2018-3-18 16:47 | 只看该作者
24c02是好的,用另一个程序就可以,两个程序比较也没找出问题
回复

使用道具 举报

5#
ID:111634 发表于 2018-3-18 19:15 | 只看该作者
本帖最后由 zl2168 于 2018-3-18 19:20 编辑

实例49  读写AT24C02
Proteus仿真一下,确认有效。
实例49 读写IIC AT24C02.rar (38.96 KB, 下载次数: 22)

有关AT24Cxx页写缓冲的概念说明如下:
由于E2PROM的半导体工艺特性,对E2PROM的写入时间需要5~10ms,但AT24Cxx系列串行E2PROM芯片内部设置了一个具有SRAM性质的输入缓冲器,称为页写缓冲器。CPU对该芯片写操作时,AT24Cxx系列芯片先将CPU输入的数据暂存在页写缓冲器内,然后,慢慢写入E2PROM中。因此,CPU对AT24Cxx系列E2PROM一次写入的字节数,受到该芯片页写缓冲器容量的限制。页写缓冲器的容量为16B,若CPU写入字节数超过芯片页写缓冲器容量,应在一页写完后,隔5~10ms重新启动一次写操作。

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。书中电路和程序设计有详细说明,程序语句条条有注解。
回复

使用道具 举报

6#
ID:111634 发表于 2018-3-18 19:17 | 只看该作者
本帖最后由 zl2168 于 2018-3-18 19:19 编辑

实例50  非零地址读写AT24C02
上节已提到AT24Cxx页写缓冲的特性,需要补充说明的是,一次写入AT24Cxx字节数不但不能超过芯片页写缓冲器容量,而且,若不是从页写缓冲器页内零地址0000写起,一次写入地址不能超出页内最大地址1111。例如,若从页内地址0000写起,一次最多可写16字节;若从页内地址0010写起,一次最多只能写16-2=14字节。若要写16字节,超出页内地址1111,将会引起地址翻卷,导致出错。因此,本例16字节从AT24C02 5BH开始写起,须分两次写入。第1次写0x5b0x5f单元,第2次写0x600x62单元,中间还必须有页写延时。
实例50 非零地址读写AT24C02.rar (39.09 KB, 下载次数: 28)

回复

使用道具 举报

7#
ID:726437 发表于 2020-4-23 20:48 | 只看该作者
我也遇到了这样的问题,刚解决,24c02写入是需要时间的,叫写入周期Twr,写入的字节并没有立即写入储存器,而是暂时储存到了另一个地方,写入存储器还需要一段时间(即Twr),写完一个字节后需延时Twr,这段时间是比较长的。
回复

使用道具 举报

8#
ID:729164 发表于 2020-4-24 10:11 | 只看该作者
24C02是2K的i2c,看是模拟的还是外设的i2c,ARM的外设i2c操作起来有时会出问题,建议试试模拟i2c方式。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

9#
ID:423923 发表于 2021-3-31 13:59 | 只看该作者
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马上读出就出现问题

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

10#
ID:63304 发表于 2021-8-2 14:09 | 只看该作者
dsy5555 发表于 2021-3-31 13:59
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马 ...

读不需要延时,不要用仿真
回复

使用道具 举报

11#
ID:973639 发表于 2021-10-20 18:00 | 只看该作者
banqiao 发表于 2018-3-18 16:47
24c02是好的,用另一个程序就可以,两个程序比较也没找出问题

我用24c02写数据时也出现了一样的问题(写奇数写无效,写偶数正常,时延设的是10ms,应该不是时延的问题),楼主目前解决了吗?望告知。另外,如果还有的话,能把成功写奇数程序发我看一下吗。
回复

使用道具 举报

12#
ID:975089 发表于 2021-10-26 14:39 | 只看该作者
楼主解决了吗,我也遇到了
回复

使用道具 举报

13#
ID:517389 发表于 2021-11-1 18:31 | 只看该作者
void IIC_stop()                 //IIC终止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
把原来的IIC终止子程序改为这样就行了。
回复

使用道具 举报

14#
ID:976819 发表于 2021-11-1 21:06 | 只看该作者
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马上读出就出现问题
回复

使用道具 举报

15#
ID:885453 发表于 2021-11-1 21:55 | 只看该作者
写数据之前要先把以前的数据擦除,再写新数据才不会出错
回复

使用道具 举报

16#
ID:399179 发表于 2021-11-29 20:55 来自手机 | 只看该作者
你们怎么解决的?我也遇到这样的问题了,有的能写入有的不能
回复

使用道具 举报

17#
ID:365802 发表于 2021-11-30 13:41 | 只看该作者
我之前也遇到过这个问题, 后来发现时延时的问题.
http://www.51hei.com/bbs/dpj-151160-1.html
回复

使用道具 举报

18#
ID:81196 发表于 2021-11-30 17:11 | 只看该作者
IIC操作,只要出了问题,肯定是IIC的时序不对,自己找问题就行了,对照时序表查看。
回复

使用道具 举报

19#
ID:796012 发表于 2021-12-7 14:46 | 只看该作者
片内要提升电压到20V左右
回复

使用道具 举报

20#
ID:1004043 发表于 2022-2-4 00:31 | 只看该作者
ybftl 发表于 2021-11-1 18:31
void IIC_stop()                 //IIC终止
{
sda=0;

解决了我的问题谢谢
回复

使用道具 举报

21#
ID:1031851 发表于 2022-6-2 20:55 | 只看该作者
ybftl 发表于 2021-11-1 18:31
void IIC_stop()                 //IIC终止
{
sda=0;

牛比牛比牛比
回复

使用道具 举报

22#
ID:139866 发表于 2022-6-3 10:20 | 只看该作者
直接用示波器采集波形,对照时序图分析,比在这让人给你猜原因快得多
回复

使用道具 举报

23#
ID:1031962 发表于 2022-6-3 13:30 | 只看该作者
AT24Cxx系列芯片先将CPU输入的数据暂存在页写缓冲器内,然后,慢慢写入E2PROM中。因此,CPU对AT24Cxx系列E2PROM一次写入的字节数,受到该芯片页写缓冲器容量的限制。页写缓冲器的容量为16B,若CPU写入字节数超过芯片页写缓冲器容量,应在一页写完后,隔5~10ms重新启动一次写操作。
回复

使用道具 举报

24#
ID:1064915 发表于 2023-4-19 15:16 | 只看该作者
用Proteus仿真,不用买开发板了?
回复

使用道具 举报

25#
ID:420836 发表于 2023-4-20 09:10 | 只看该作者
奇数与偶数对EEPROM芯片没有区别,是否尝试在代码中将奇数与偶数切换?
回复

使用道具 举报

26#
ID:1065084 发表于 2023-4-20 09:49 | 只看该作者

看看你写的错误:
void IIC_stop()                //IIC终止
{
        scl=1;
        sda=0;
        delay();
        sda=1;
        delay();
}
如果你的数据为偶数 即最后一位为0,程序执行正常
如果,你数据为奇数,你最后一位为1 那 执行就是 sda=1;scl=1;sda=0;是不是和起始信号一样?

让你去学习,你就非要自己闭门造车,如果你自己写的程序我敬你是个汉子,如果你抄的别人的我建议你给他一巴掌,如果是你照葫芦画瓢画出来的,建议你给自己两巴掌
回复

使用道具 举报

27#
ID:996773 发表于 2023-4-20 13:25 | 只看该作者
看了一下要笑死,一个24c02基础东西都玩的五花八门,有提高电压的,有先擦后写的

还有直接仿真的,难道你们的产品都是在仿真上想出来的吗。还有抄的,这个程序

还要抄,以后还能做啥大工程,楼主的问题更离谱:非得去写奇数或偶数,写00000000

不行吗,写11111111不行吗。我这个汇编两年的新手要被你们笑死,不说了,送外卖了,要超时了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表