有關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) //寫一個字節(jié)函數 { 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() //讀一個字節(jié)函數 { 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) //指定地址寫一個字節(jié) { start(); write_byte(0xa0); respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); } uchar read_add(uchar address) //指定地址讀一個字節(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初始化函數 { 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)); } }
作者: admin 時間: 2010-7-30 19:31
給你一個 100% 沒有問題的程序
http://www.torrancerestoration.com/bbs/dpj-2807-1.html
作者: 渴望壯大 時間: 2017-9-14 10:55
admin 發(fā)表于 2010-7-30 19:31
給你一個 100% 沒有問題的程序
http://www.torrancerestoration.com/bbs/dpj-2807-1.html
謝謝分享
歡迎光臨 (http://www.torrancerestoration.com/bbs/) | Powered by Discuz! X3.1 |