找回密码
 立即注册

QQ登录

只需一步,快速开始

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

AT24C02

[复制链接]
跳转到指定楼层
楼主
ID:25346 发表于 2010-7-30 14:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

有关AT24C02芯片的断电记忆功能总是无法实现  望各位指点指点!

/*12M晶振实现数码管显示时间,日期与年月,星期,闹钟,并实现信息可调*/

#include<at89x52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
bit write=0;  //写24c02的标志
sbit sda=P1^0;
sbit scl=P1^1;
sbit dula=P3^6;//段选
sbit wela=P3^7;//位选
uchar sec,tcnt;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; 
uchar n,a; 
uchar hh,mm,ss; 
uchar nhh,nmm,nss; 
uint year,year3;
uchar day,mon,week,year1,year2; 
uchar hhs,hhg,mms,mmg,sss,ssg; 
uchar days,dayg,mons,mong; 
uchar nhhs,nhhg,nmms,nmmg,nsss,nssg; 
uchar set1=1,set2=1;
sbit fm=P3^4; 
sbit k1=P3^0;   //时间显示切换键
sbit k2=P3^1;   //移位功能键
sbit k3=P3^2;  //加法按键
sbit k4=P3^3;  //减法按键
uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年 
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年 
 void baoshi(); 
void alarm(); 
void set_time(); 
void set_alarm(); 
void set_mdw(); 
void key_change(); 
void key_set();


void display(uchar,uchar,uchar);
void display5(uchar);

void delay1()
 {;}
void delay(uchar xms)
 {
   uint i,j;
   for(i=xms;i>0;i--)
      for(j=0;j<300;j++);
 }
 
 void di()
 {
   fm=0;
   delay(10);
   fm=1;
 }
void delayms(uint xms)
{
  uint i,j;
  for(i=xms;i>0;i--)
     for(j=110;j>0;j--);
}

 void start()  //开始函数
  {
    sda=1;
 delay1();
 scl=1;
 delay1();
 scl=0;
 delay1();
  }
  void stop()   //停止函数
  {
    sda=0;
 delay1();
 scl=1;
 delay1();
 sda=1;
 delay1();
  }
  void respons()  //回应函数
  {
    uchar i;
 scl=1;
 delay1();
 while((sda==1)&&(i<250))i++;
 scl=0;
 delay1();
  }
   void write_byte(uchar date)    //写一个字节函数
  {
    uchar temp,i;
 temp=date;
 for(i=0;i<8;i++)
 {
   temp=temp<<1;
   scl=1;
   delay1();
   sda=CY;
   delay1();
   scl=1;
   delay1();
 }
 scl=0;
 delay1();
 sda=1;
 delay1();
  }
  uchar read_byte()   //读一个字节函数
  {
    uchar i,k;
 scl=0;
 delay1();
 sda=1;
 delay1();
 for(i=0;i<8;i++)
 {
   scl=1;
   delay1();
   k=(k<<1)|sda;
   scl=0;
   delay1();
 }
 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 init_24c02()    //I2C初始化函数
  {
    sda=1;
 delay1();
 scl=1;
 delay1();

  }
 void init()
 {
   dula=0;    //关闭两个锁存器锁存端,防止数码管出现乱码
   wela=0;

   hh=8;mm=0;ss=0;        //时钟
   nhh=6;nmm=0;nss=0;      //闹钟     
   year=2010;mon=7;day=3;week=6;
   year3=year-year/100*100;
   init_24c02();
   display(year3,mon,day);
   display(hh,mm,ss);
   display(nhh,nmm,nss);
   

   //display1(); //正常显示年月日
   year3=read_add(1);mon=read_add(2);day=read_add(3);
   display(year3,mon,day);
   delay(500);

   hh=read_add(4);mm=read_add(5);ss=read_add(6);
   display(hh,mm,ss);
   delay(500);

   nhh=read_add(7);nmm=read_add(8);nss=read_add(9);
   display(nhh,nmm,nss);
   delay(500);

   TMOD=0x11; 
   TH0=0x3c;TL0=0xb1;
   TH1=0x3c;TL1=0xb1;
   EA=1;
   TR0=1;ET0=1; 
   TR1=1;ET1=1;
    
 }     

 void main()
 {
   hhs=hh/10%10;//时 
   hhg=hh%10; 
   mms=mm/10%10;  //分        
   mmg=mm%10; 
   sss=ss/10%10;  //秒
   ssg=ss%10; 
   nhhs=nhh/10%10;//闹钟时 
   nhhg=nhh%10; 
   nmms=nmm/10%10;  //闹钟分
   nmmg=nmm%10; 
   nsss=nss/10%10;  //闹钟秒
   nssg=nss%10; 
   dayg=day/10%10;  //日 
   days=day%10; 
   mons=mon/10%10;  //月
   mong=mon%10;
   year1=year3/10%10;  //年个位
   year2=year3%10;     //年十位

   init();
   while(1)       
  { 
   key_change();       //k1按键扫描 
   key_set();         //k2按键扫描 
   set_time();        //设置时间 
   set_mdw();         //设置年月日
   set_alarm();      //设置闹钟
   
   
 if(set1==1)display(read_add(1),read_add(2),read_add(3));
 if(set1==2)display(read_add(1),read_add(2),read_add(3));
 if(set1==3)display(read_add(4),read_add(5),read_add(6));
 if(set1==4)display(read_add(4),read_add(5),read_add(6));
 if(set1==5)display5(read_add(7));
 if(set1==6)display(read_add(8),read_add(9),read_add(10));
 if(set1==7)display(read_add(8),read_add(9),read_add(10));

  }
 }

void display(uchar a,uchar b,uchar c) //
{
  uchar a1,a2;uchar b1,b2;uchar c1,c2;
  a1=a/10%10;a2=a%10;
  b1=b/10%10;b2=b%10;
  c1=c/10%10;c2=c%10;

  dula=1;P0=tab[a1];dula=0;P2=0xff;wela=1;P2=0x01;wela=0;delay(1); 
  dula=1;P0=tab[a2];dula=0;P2=0xff;wela=1;P2=0x02;wela=0;delay(1); 
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x04;wela=0;delay(1);  
  dula=1;P0=tab[b1];dula=0;P2=0xff;wela=1;P2=0x08;wela=0;delay(1); 
  dula=1;P0=tab[b2];dula=0;P2=0xff;wela=1;P2=0x10;wela=0;delay(1); 
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x20;wela=0;delay(1);  
  dula=1;P0=tab[c1];dula=0;P2=0xff;wela=1;P2=0x40;wela=0;delay(1); 
  dula=1;P0=tab[c2];dula=0;P2=0xff;wela=1;P2=0x80;wela=0;delay(1); 
}
void diplay5(uchar a)    //
{
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x01;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x02;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x04;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x08;wela=0;delay(1);
  dula=1;P0=tab[a];dula=0;P2=0xff;wela=1;P2=0x10;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x20;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x40;wela=0;delay(1);
  dula=1;P0=tab[10];dula=0;P2=0xff;wela=1;P2=0x80;wela=0;delay(1);

}


uchar incone(uchar n) //加1函数 
{ 
  if(k3==0) 
   {delay(20); 
    if(k3==0) 
     { 
       n++; 
       while(!k3);
    di();
    
      } 
    } 
   return(n); 
}

uchar decone(uchar m) //减1函数 
{ 
   if(k4==0) 
    {
  delay(20);
  if(k4==0) 
       { 
         m--; 
         while(!k4);
   di(); 
         if(m<0) 
           {m=0;} 
        } 
     } 
   return(m); 
}

void key_change() //k1按键扫描 
{ 
  if(k1==0) 
   { 
     delay(20); 
     if(k1==0)   //确认切换键被按下
       { 
         set1++;    //纪录切换键被按下次数
          while(!k1); //释放确定
    di();
        if(set1==8) 
             {set1=1;}
     
       } 
    }
 
}

void key_set() //k2按键扫描 
{ 
  if(k2==0) 
   { 
     delay(20); 
     if(k2==0) 
       { 
         set2++; 
         while(!k2);
   di(); 
         if(set2==4) 
           {set2=1;} 
       } 
    } 
}

void baoshi() //整点报时函数 
{ 
  if(mm==00&&ss==00) 
    {fm=0;} 
   if(ss==1) 
    {fm=1;} 
}

void alarm() //闹钟函数 
{ 
  uchar x; 
  if(nhh==0) 
   { 
     goto end; 
   } 
   if(hh==nhh&&mm==nmm&&ss==nss) 
   { 
   for(x=0;x<6;x++) 
     { 
       fm=0;delay(30);fm=1;delay(20); 
       fm=0;delay(30);fm=1;delay(20);
       fm=0;delay(30);fm=1;delay(20); 
       fm=0;delay(30);fm=1;delay(160);
     
     } 
   } 
   end:; 
}

void set_time() //设置时间函数 
{ 
  if(set1==4) 
   { 
    if(set2==1) 
      { 
        hh=incone(hh); 
        if(hh==24) 
          {hh=0;} 
        if(hh==-1) 
          {hh=23;} 
        hh=decone(hh);
  write_add(4,hh); 
      } 
     if(set2==2) 
      { 
        mm=incone(mm); 
        if(mm==60) 
          {mm=0;} 
        if(mm==-1) 
          {mm=59;} 
        mm=decone(mm); 
     write_add(5,mm);
      } 
      if(set2==3) 
      { 
        ss=incone(ss); 
        if(ss==60) 
          {ss=0;} 
        if(ss==-1) 
          {ss=59;} 
        ss=decone(ss);
     write_add(6,ss);
       } 
    }
 
   
     
}

void set_mdw() //设置年月日 
{ 
if(set1==2) 
{ 
  if(set2==1)
  {
    year3=incone(year3);
 if(year3>99)
   { year3=0;}
 year3=decone(year3);
 if(year3<0)
   { year3=0;}
 write_add(1,year3);   //在24C02的地址1中写入数据year3年
 }
  if(set2==2)
  {
    mon=incone(mon); 
    if(mon==13) 
      { mon=1;} 
    mon=decone(mon); 
    if(mon==0) 
      {mon=12;}
    write_add(2,mon);       //在24C02的地址2中写入数据mon年
  }
  if(set2==3)
  {
    day=incone(day); 
    if(day==32) 
      {day=1;} 
    day=decone(day); 
    if(day==0) 
      {day=31;}
    write_add(3,day);     //在24C02的地址1中写入数据day日

  }

} 
}

void set_alarm() //设置闹钟函数 
{ 
  if(set1==7) 
    { 
      if(set2==1) 
        { 
          nhh=incone(nhh); 
          if(nhh==24) 
            {nhh=0;write_add(8,nhh);} 
          if(nhh==-1) 
            {nhh=23;write_add(8,nhh);} 
          nhh=decone(nhh);
    write_add(8,nhh); 
        } 
     if(set2==2) 
       { 
         nmm=incone(nmm); 
         if(nmm==60) 
           {nmm=0;write_add(9,nmm);} 
         nmm=decone(nmm); 
         if(nmm==-1) 
           {nmm=59;write_add(9,nmm);} 
   write_add(9,nmm);
       } 
     if(set2==3) 
       { 
         nss=incone(nss); 
         if(nss==60) 
           {nss=0;write_add(10,nss);} 
         nss=decone(nss); 
         if(nss==-1) 
           {nss=59;write_add(10,nss);}
   write_add(10,nss); 
       } 
    }
 
}


void timer1() interrupt 3
{
   TH1=(65536-50000)/256;//再次装定时器初值
 TL1=(65536-50000)%256;
 a++;
 if(a<100)display(year3,mon,day);
    if(a>100&&a<200)display(hh,mm,ss);
    if(a>200&&a<300)display(nhh,nmm,nss);
 if(a>300)a=0;

}
void timer0() interrupt 1//定时器0中断服务程序
{
 TH0=(65536-50000)/256;//再次装定时器初值
 TL0=(65536-50000)%256;
 n++;  //中断次数累加
 if(n==20) //20次50毫秒为1秒
 {
  n=0;
  ss++;
  if(ss==60)//秒加到60则进位分钟
  {
   ss=0;//同时秒数清零
   mm++;
   if(mm==60)//分钟加到60则进位小时
   {
    mm=0;//同时分钟数清零
    hh++;
    if(hh==24)//小时加到24则小时清零
    {
     hh=0;
     day++;week++;
     if(week==8)
       {week=0;}
     write_add(7,week);
     if(year%4==0&&year%100!=0||year%400==0) //闰年
       {if(day==table1[mon]+1)
           { day=0;mon++;
             if(mon==13)
                {mon=0;year++;
           write_add(1,year3);
        }
             write_add(2,mon);
            }
        write_add(3,day);
          }
      else    //非闰年
      {
        if(day==table2[mon]+1)
          {day=0;mon++;
        if(mon==13)
           {mon=0;year++;
         write_add(1,year3);
         }
        write_add(2,mon);        
       }
      write_add(1,day);
      }
    }
    write_add(4,hh);//数据改变立即存入24C02
     display(read_add(4),read_add(5),read_add(6));
   }
    write_add(5,mm);//数据改变立即存入24C02
   display(read_add(4),read_add(5),read_add(6));
  }
   write_add(6,ss);//数据改变立即存入24C02
  display(read_add(4),read_add(5),read_add(6));
 } 
}



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

使用道具 举报

沙发
ID:1 发表于 2010-7-30 19:31 | 只看该作者

给你一个 100% 没有问题的程序

http://www.51hei.com/bbs/dpj-2807-1.html

回复

使用道具 举报

板凳
ID:188935 发表于 2017-9-14 10:55 | 只看该作者
admin 发表于 2010-7-30 19:31
给你一个 100% 没有问题的程序
http://www.51hei.com/bbs/dpj-2807-1.html

谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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