打印
[国产单片机]

关于EEPROM擦写次数

[复制链接]
14253|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
grouplake|  楼主 | 2015-4-30 11:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

/***********************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
bit  write=0;           //写24C02的标志;
sbit sda=P3^7;                        
sbit scl=P3^6;
sbit duan=P2^0;
sbit wei=P2^1;
uchar sec,tcnt;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,//0,1,2,3,4,5,6,7//共阳数码管
                                        0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};//8,9,A,b,C,d,E,F
/**********************************************************************/
void delay()//4~5us延时
{ ;; }
void delay1ms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
/**********************************************************************/

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

/********************************/
void stop() //停止
{
        sda=0;
        delay();
        scl=1;
        delay();
        sda=1;
        delay();
}
/********************************/

/********************************/
void respons()  //应答
{
        uchar i;
        scl=1;
        delay();
        while((sda==1)&&(i<250))i++;
        scl=0;
        delay();
}
/********************************/

/********************************/
void init()//初始化函数
{
        sda=1;
        delay();
        scl=1;
        delay();
}
/********************************/

/********************************/
void write_byte(uchar date)//写一个字节
{
        uchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
                temp=temp<<1;
                scl=0;
            delay();
                sda=CY;
                delay();
                scl=1;
                delay();
        }
        scl=0;
        delay();
        sda=1;
        delay();
}
/********************************/

/********************************/
uchar read_byte()//读一个字节
{
        uchar i,k;
        scl=0;
        delay();
        sda=1;
        delay();
        for(i=0;i<8;i++)
        {
                scl=1;
                delay();       
                k=(k<<1)|sda;
                scl=0;
                delay();       
        }
        return k;
}
/********************************/

/********************************/
void write_add(uchar address,uchar date)//写一个字节数据
{
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        write_byte(date);
        respons();
        stop();
}
/********************************/

/********************************/
uchar read_add(uchar address)//读一个字节数据
{
        uchar date;
        start();
        write_byte(0xa0);
        respons();
        write_byte(address);
        respons();
        start();
        write_byte(0xa1);
        respons();
        date=read_byte();
        stop();
        return date;
}
/********************************/

/********************************/
void display(uchar bai_c,uchar sh_c)        //显示程序
{
   wei=1;
   P0=0x02;
   wei=0;
   duan=1;
   P0=table[bai_c];                //显示第一位
   duan=0;
   delay1ms(5);

   wei=1;
   P0=0x01;
   wei=0;
   duan=1;
   P0=table[sh_c];                //显示第二位
   duan=0;
   delay1ms(5);
}
/********************************/

/********************************/
void main()
{
        init();
        sec=read_add(2);    //读出保存的数据赋于sec
        if(sec>100)        //防止首次读取出错误数据
                sec=0;
        TMOD=0x01;                          //定时器工作在方式1
        ET0=1;
        EA=1;
        TH0=(65536-50000)/256; //对TH0 TL0赋值
        TL0=(65536-50000)%256; //使定时器0.05秒中断一次
        TR0=1;                 //开始计时
        while(1)
        {
                display(sec/10,sec%10);
                if(write==1)                       //判断计时器是否计时一秒
                {
                        write=0;              //清零
                        write_add(2,sec);            //在24c02的地址2中写入数据sec
                }
        }
}
/********************************/

/********************************/
void t0() interrupt 1 //定时中断服务函数
{
        TH0=(65536-50000)/256; //对TH0 TL0赋值
        TL0=(65536-50000)%256; //重装计数初值
        tcnt++;        //每过50ms tcnt加一
        if(tcnt==20)  //计满20次(1秒)时
        {
            tcnt=0;   //重新再计
            sec++;
            write=1;  //1秒写一次24C02
            if(sec==100) //定时100秒,再从零开始计时
                    sec=0;
        }
}
/********************************/

在网上看到如上 的EEPROM应用程序,有几个疑问请教大家:

1. AT24C02 规格书上写擦写次数>1万次, 这里的次数是指从【擦除到写入】算一次吗?
2.既然有次数的限制,怎么把这个语句write_add(2,sec);            //在24c02的地址2中写入数据sec 放在   while(1)循环里面呢?
3. 国产的STC单片机宣传片内的EEPROM擦写次数达到10万次。即便擦写次数再多,放在while(1)循环里面也是很快就用完了。




相关帖子

沙发
hgjinwei| | 2015-4-30 13:06 | 只看该作者
本来就是一个测试程序

使用特权

评论回复
板凳
JY-DX-JY| | 2015-5-1 18:37 | 只看该作者
一般不会这么用的。

使用特权

评论回复
地板
lcdi| | 2015-5-7 11:08 | 只看该作者
本帖最后由 lcdi 于 2015-5-7 11:15 编辑

程序里还有个判断条件,1秒写一次。算起来1天多也就over了。
所以这个用法实在很“2”,没考虑到器件寿命和可靠性。实际应用中可不要这样~

使用特权

评论回复
5
lrhsx33| | 2015-5-8 16:10 | 只看该作者
说明一下AT24C02 写 100万次。
EEPROM 单片机,1-10万次左右。
读是不算这个寿命的。
实际产品中,你可以先读比较数据,相同不写,只有数据改变再去写。
如果数据一直改变,那就等他不变的时候再去写。这样可以用到单片机坏都没有问题。

使用特权

评论回复
6
mailshichao| | 2017-9-20 10:41 | 只看该作者
lrhsx33 发表于 2015-5-8 16:10
说明一下AT24C02 写 100万次。
EEPROM 单片机,1-10万次左右。
读是不算这个寿命的。

还有方法就是,数据保存到不同的位置,每次开机都读写不同的地址

使用特权

评论回复
7
山东电子小菜鸟| | 2017-9-20 12:35 | 只看该作者
为什么要放在WHILE中,eeprom一般是存储重要数据的,如果非要放在while中那你就几分钟擦鞋一次,这样也能好几年

使用特权

评论回复
8
ningling_21| | 2017-9-20 15:39 | 只看该作者
专门测试 擦写次数的程序

使用特权

评论回复
9
xhtwork| | 2017-9-20 15:59 | 只看该作者
我以前测试过24Cxx、FLASH,都远超datasheet给出的可擦写次数。但测试品种少、数量少,没有普遍意义。

使用特权

评论回复
10
ddllxxrr| | 2017-9-20 20:21 | 只看该作者
一般FLASH十万次,铁电100万次。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

18

帖子

0

粉丝