标题: 单片机EEPROM 24C02 不能写入奇数,请高手解答 [打印本页]

作者: banqiao    时间: 2018-3-18 14:12
标题: 单片机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);
}



作者: zl2168    时间: 2018-3-18 16:04
换一片24c02试试
作者: hds1988_xjtu    时间: 2018-3-18 16:11
24C02应该是很简单的的,建议楼主不要自己写,网上找一大堆例子
作者: banqiao    时间: 2018-3-18 16:47
24c02是好的,用另一个程序就可以,两个程序比较也没找出问题

作者: zl2168    时间: 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案例,用于仿真实验操作,电路与程序真实可靠可信可行。书中电路和程序设计有详细说明,程序语句条条有注解。

作者: zl2168    时间: 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)


作者: Mr.haohao    时间: 2020-4-23 20:48
我也遇到了这样的问题,刚解决,24c02写入是需要时间的,叫写入周期Twr,写入的字节并没有立即写入储存器,而是暂时储存到了另一个地方,写入存储器还需要一段时间(即Twr),写完一个字节后需延时Twr,这段时间是比较长的。
作者: fendouzhe    时间: 2020-4-24 10:11
24C02是2K的i2c,看是模拟的还是外设的i2c,ARM的外设i2c操作起来有时会出问题,建议试试模拟i2c方式。
作者: dsy5555    时间: 2021-3-31 13:59
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马上读出就出现问题
作者: 740071911    时间: 2021-8-2 14:09
dsy5555 发表于 2021-3-31 13:59
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马 ...

读不需要延时,不要用仿真
作者: dkdie    时间: 2021-10-20 18:00
banqiao 发表于 2018-3-18 16:47
24c02是好的,用另一个程序就可以,两个程序比较也没找出问题

我用24c02写数据时也出现了一样的问题(写奇数写无效,写偶数正常,时延设的是10ms,应该不是时延的问题),楼主目前解决了吗?望告知。另外,如果还有的话,能把成功写奇数程序发我看一下吗。
作者: 合金装备布狼牙    时间: 2021-10-26 14:39
楼主解决了吗,我也遇到了
作者: ybftl    时间: 2021-11-1 18:31
void IIC_stop()                 //IIC终止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
把原来的IIC终止子程序改为这样就行了。
作者: sunjielayout    时间: 2021-11-1 21:06
不管读写,都要延时,不然导致波形不对,在写完一字节后,马上读出也不行,我仿真搞了好久才明白,写进后马上读出就出现问题
作者: 2844746961    时间: 2021-11-1 21:55
写数据之前要先把以前的数据擦除,再写新数据才不会出错
作者: 快乐眼泪    时间: 2021-11-29 20:55
你们怎么解决的?我也遇到这样的问题了,有的能写入有的不能
作者: ping264888    时间: 2021-11-30 13:41
我之前也遇到过这个问题, 后来发现时延时的问题.
http://www.51hei.com/bbs/dpj-151160-1.html
作者: shumivan    时间: 2021-11-30 17:11
IIC操作,只要出了问题,肯定是IIC的时序不对,自己找问题就行了,对照时序表查看。
作者: 玉萌业余发展    时间: 2021-12-7 14:46
片内要提升电压到20V左右
作者: 苍月一号    时间: 2022-2-4 00:31
ybftl 发表于 2021-11-1 18:31
void IIC_stop()                 //IIC终止
{
sda=0;

解决了我的问题谢谢
作者: pios    时间: 2022-6-2 20:55
ybftl 发表于 2021-11-1 18:31
void IIC_stop()                 //IIC终止
{
sda=0;

牛比牛比牛比
作者: 天ノ忆    时间: 2022-6-3 10:20
直接用示波器采集波形,对照时序图分析,比在这让人给你猜原因快得多
作者: 电子狂人1    时间: 2022-6-3 13:30
AT24Cxx系列芯片先将CPU输入的数据暂存在页写缓冲器内,然后,慢慢写入E2PROM中。因此,CPU对AT24Cxx系列E2PROM一次写入的字节数,受到该芯片页写缓冲器容量的限制。页写缓冲器的容量为16B,若CPU写入字节数超过芯片页写缓冲器容量,应在一页写完后,隔5~10ms重新启动一次写操作。
作者: joyb    时间: 2023-4-19 15:16
用Proteus仿真,不用买开发板了?
作者: TTQ001    时间: 2023-4-20 09:10
奇数与偶数对EEPROM芯片没有区别,是否尝试在代码中将奇数与偶数切换?
作者: yuxuesuixing    时间: 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;是不是和起始信号一样?

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

作者: hi等你    时间: 2023-4-20 13:25
看了一下要笑死,一个24c02基础东西都玩的五花八门,有提高电压的,有先擦后写的

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

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

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




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1