打印
[DemoCode下载]

24C02程序,51核心。

[复制链接]
1144|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
玛尼玛尼哄|  楼主 | 2016-3-23 18:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
给别人做的个东西,要求数据掉电保存,大的框架很早就搭建起来了,但是到了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++;

        }        
}
沙发
芙蓉洞| | 2016-3-23 20:21 | 只看该作者
新唐的51单片机速度怎么样,有低功耗的吗?

使用特权

评论回复
板凳
玛尼玛尼哄|  楼主 | 2016-3-23 21:00 | 只看该作者
芙蓉洞 发表于 2016-3-23 20:21
新唐的51单片机速度怎么样,有低功耗的吗?

51都没有低功耗,不能进行休眠。

使用特权

评论回复
地板
Jessicakjdsl| | 2016-3-26 23:50 | 只看该作者
用IO口模拟的i2c,速度上不去,不过一般器件也就到44k,够用了

使用特权

评论回复
5
玛尼玛尼哄|  楼主 | 2016-4-5 17:04 | 只看该作者
Jessicakjdsl 发表于 2016-3-26 23:50
用IO口模拟的i2c,速度上不去,不过一般器件也就到44k,够用了

用IIC的应用,速度都是不高的,就那么几个字节存储,够了

使用特权

评论回复
6
598330983| | 2016-4-6 14:02 | 只看该作者
无论是智能仪器仪表还是单片机工业控制系统都要求其数据能够安全可靠而不受干扰,特别是一些重要的设定参数(如温度控制设定值)受到干扰后变成一个很大的数字,这时就有可能发生烧箱毁物的破坏性后果,给生产和经济带来损失,因此必须选用可靠的24C02器件作为数据储存单元。
因此这样的应用,我们可以用多余的空间来重复的写。

使用特权

评论回复
7
Micachl| | 2016-4-11 11:27 | 只看该作者
是不是i2c的sck速度设置的太快了?

使用特权

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

本版积分规则

179

主题

3081

帖子

2

粉丝