24C02终于搞定了!分享程序给需要的坛友,最大存储255字节!

2020-01-15 19:20发布

给别人做的个东西,要求数据掉电保存,大的框架很早就搭建起来了,但是到了24C02这,卡住了。不是无法实现存储,只是我的数据量比较大,好几天在网上搜索24C02相关的程序,几乎把所有的能看的都看遍了,我失望的才发现,大同小异,大家都是互相抄来抄去的,没有一个能很好用的,而且有的程序又是缺个括号,或者只有括号的一半,另一半和里边的变量都不知道跑哪去了,看的很是郁闷啊,开始想,不到万不得已,坚决不看英文的技术手册,今早一大早泡图书馆看书查资料,复印了好几十页,到了实验室又打印了技术文档,边看边查单词边翻译,还有在我的好兄弟的一起协助下,终于轻松实现了24C02存储255个数据。同时也大体明白了24C02得工作原理。
1、24C02是2Kbits 意思是有2048bit,换算成字节是256Byte,也就是说最多可以存储255个字节的数据;
2、ATMEl24C02(应该其他厂家的24C02也是这样子吧。。。)有32页,每页可以存放8个字节;
3、24C02有两种工作模式:(1)、字节写入模式:结合技术文档我认为该模式是这样工作的:首先是可以再任意的地址(0x00~0xFF)写入一个字节,也可以在某一地址连续的写入N字节,而且不需要翻页,从技术手册得知,答题时说字节写入模式下,页指针根写入数据的多少来自动增加实现翻页功能,不用自己在程序里边实现;
                                      (2)、页写入模式:页写入模式下,手册上写着,一页可以存8字节,当存储的数据大于8时,则会覆盖先前保存的数据,例如,有16个数据 uchar data[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},从24C02的0x00地址开始存放,当存完一页(8个)时,第9个数据会保存在0x00,覆盖掉开始保存的1,后边的数据一次类推,这样的现象叫做“翻转”,如果想写完一页后将剩余的数据保存在下一页,页指针需要自己来设定。
我觉着,字节写入模式相对更简单些。
下边,附上我的程序,供大家参考,如有疑问的地方,欢迎大家交流!
///使用单片机:89S51
///晶振:12MHz
#include<reg52.h>
#include "INTRINS.H"
#define uchar unsigned char
#define uint unsigned int

sbit scl = P3^2;
sbit sda = P3^3;
/*********74H573控制端*********/
sbit dula = P2^7;//段选
sbit wela = P2^6;//位选


sbit LED = P2^5;//秒显示
uchar tt=0;
uchar i=0,j=0,temp=0,a=0,b=0,c=0;
/*******数码管段选_时间********/
uchar code table_duan[]={0x3f,0x06,0x5b,0x4f,0x66,
                                             0x6d,0x7d,0x07,0x7f,0x6f};
/*********数码管位选**********/
uchar code table_wei[]={0xfe,0xfd,0xfb,0xf7,0xef};

void delay1(uint x)
{
    uint i,j ;
    for(i=x;i--;i>0)
    for(j=110;j--;j>0);
}

/**************************** 显示函数 **************************/
void display(uchar wee,uchar H_hour,uchar L_hour,uchar H_min,uchar L_min)
{
        dula=1;
        P0=table_duan[wee];//数码管5位,星期
        dula=0;
        wela=1;
        P0=table_wei[0];
        wela=0;       
        delay1(1);

        dula=1;
        P0=table_duan[H_hour];//数码管4位,小时十位
        dula=0;
        wela=1;
        P0=table_wei[1];
        wela=0;       
        delay1(1);

        dula=1;
        P0=table_duan[L_hour];//数码管3位,小时个位
        dula=0;
        wela=1;
        P0=table_wei[2];
        wela=0;       
        delay1(1);

        dula=1;
        P0=table_duan[H_min];//数码管2位,分钟十位
        dula=0;
        wela=1;
        P0=table_wei[3];
        wela=0;       
        delay1(1);

        dula=1;
        P0=table_duan[L_min];//数码管1位,分钟个位
        dula=0;
        wela=1;
        P0=table_wei[4];
        wela=0;       
        delay1(1);
}

void delay()
{ ;; }
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();
        }
        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;
}
/*-------------------------------------------------------------
主程序
功能:实现存储器EEPROM AT24C02的数据读写操作
------------------------------------------------------------*/
void main()
{
        TMOD=0x01;//设置定时器0为工作方式1
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;//开总中断
        ET0=1;//开定时器0中断
    TR0=0;//启动定时器0       
        P2=P2&0xc0;
        init();
        for(i=0; i<255; i++)
        {
                write_add(i,i);
                delay1(1);
        }
        TR0=1;
        while(1)
        {
                if(j == 255)j=0;
                TR0=0;
                temp=read_add(j);
                TR0=1;       
                a=temp/100;
                b=temp%100/10;
                c=temp%100%10;
                display(a,b,c,0,0);
        }
}

void timer0() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        tt++;
        if(tt == 5)
        {
                tt = 0;
                LED = ~LED;//用于指示是否工作正常
                j++;

        }       
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
100条回答
wye11083
2020-01-20 11:56
。。。从不把I2C放眼里,当年用电脑并口跑I2C无比畅快,写过不知多少I2C器件,读过不知多少I2C器件,重力加速计,触摸屏,====,24C02写入速度不快,写一个字节必须得等待几个ms,否则就写不进去,这个。。。只能怪LZ手册不仔细看。手册里写的数据,按最长的跑时序,一点问题都不会有。想当年用并口时也没有说花几天时间整啊,程序编出来,加几个Sleep,效果马上就能看到啊。

一周热门 更多>