有關(guān)AT24C02芯片的斷電記憶功能總是無(wú)法實(shí)現(xiàn) 望各位指點(diǎn)指點(diǎn)!
/*12M晶振實(shí)現(xiàn)數(shù)碼管顯示時(shí)間,日期與年月,星期,鬧鐘,并實(shí)現(xiàn)信息可調(diào)*/
#include<at89x52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
bit write=0; //寫(xiě)24c02的標(biāo)志
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; //時(shí)間顯示切換鍵
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() //開(kāi)始函數(shù)
{
sda=1;
delay1();
scl=1;
delay1();
scl=0;
delay1();
}
void stop() //停止函數(shù)
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
void respons() //回應(yīng)函數(shù)
{
uchar i;
scl=1;
delay1();
while((sda==1)&&(i<250))i++;
scl=0;
delay1();
}
void write_byte(uchar date) //寫(xiě)一個(gè)字節(jié)函數(shù)
{
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() //讀一個(gè)字節(jié)函數(shù)
{
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) //指定地址寫(xiě)一個(gè)字節(jié)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address) //指定地址讀一個(gè)字節(jié)
{
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初始化函數(shù)
{
sda=1;
delay1();
scl=1;
delay1();
}
void init()
{
dula=0; //關(guān)閉兩個(gè)鎖存器鎖存端,防止數(shù)碼管出現(xiàn)亂碼
wela=0;
hh=8;mm=0;ss=0; //時(shí)鐘
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;//時(shí)
hhg=hh%10;
mms=mm/10%10; //分
mmg=mm%10;
sss=ss/10%10; //秒
ssg=ss%10;
nhhs=nhh/10%10;//鬧鐘時(shí)
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; //年個(gè)位
year2=year3%10; //年十位
init();
while(1)
{
key_change(); //k1按鍵掃描
key_set(); //k2按鍵掃描
set_time(); //設(shè)置時(shí)間
set_mdw(); //設(shè)置年月日
set_alarm(); //設(shè)置鬧鐘
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函數(shù)
{
if(k3==0)
{delay(20);
if(k3==0)
{
n++;
while(!k3);
di();
}
}
return(n);
}
uchar decone(uchar m) //減1函數(shù)
{
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) //確認(rèn)切換鍵被按下
{
set1++; //紀(jì)錄切換鍵被按下次數(shù)
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() //整點(diǎn)報(bào)時(shí)函數(shù)
{
if(mm==00&&ss==00)
{fm=0;}
if(ss==1)
{fm=1;}
}
void alarm() //鬧鐘函數(shù)
{
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() //設(shè)置時(shí)間函數(shù)
{
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() //設(shè)置年月日
{
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中寫(xiě)入數(shù)據(jù)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中寫(xiě)入數(shù)據(jù)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中寫(xiě)入數(shù)據(jù)day日
}
}
}
void set_alarm() //設(shè)置鬧鐘函數(shù)
{
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;//再次裝定時(shí)器初值
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//定時(shí)器0中斷服務(wù)程序
{
TH0=(65536-50000)/256;//再次裝定時(shí)器初值
TL0=(65536-50000)%256;
n++; //中斷次數(shù)累加
if(n==20) //20次50毫秒為1秒
{
n=0;
ss++;
if(ss==60)//秒加到60則進(jìn)位分鐘
{
ss=0;//同時(shí)秒數(shù)清零
mm++;
if(mm==60)//分鐘加到60則進(jìn)位小時(shí)
{
mm=0;//同時(shí)分鐘數(shù)清零
hh++;
if(hh==24)//小時(shí)加到24則小時(shí)清零
{
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);//數(shù)據(jù)改變立即存入24C02
display(read_add(4),read_add(5),read_add(6));
}
write_add(5,mm);//數(shù)據(jù)改變立即存入24C02
display(read_add(4),read_add(5),read_add(6));
}
write_add(6,ss);//數(shù)據(jù)改變立即存入24C02
display(read_add(4),read_add(5),read_add(6));
}
}
|