這個是用AT24C02和51單片機做得本來只差年的拆分了,其他部分都可以正常變化,因為AT24C02一個地址只能存一字節(jié),結果后來自己調的年月份都有問題,我直接在write_add里給除年以外的月份,日,小時賦正常值,結果有時只會有一個比如月份變化,其他的幾個沒變化,我懷疑是不是EEPORM有啥問題,為啥我直接賦值都沒變化,每次賦值后我還RESET了一下然后再重啟,求大佬解決一下,調了幾天了。
- /***************************************************
- 程序功能:實現(xiàn)一個萬年歷
- 拓展模塊:之后加GPS定位和溫度數(shù)據(jù)以及紅外遙控
- ***************************************************/
- #include<reg52.h>
- #include<string.h>
- #include<stdio.h>
- #define uchar unsigned char
- #define unit unsigned int
- unit nian;
- uchar yue,ri,shi,feng,miao; //將這些數(shù)據(jù)定義為全局變量,因為等下會對他們進行計數(shù)
- unit num,num0; //通過對功能選擇鍵按的次數(shù)進行計數(shù)來選擇對年月日還是時分秒進行修改
- unit number;
- sbit lcden=P2^5;
- sbit lcdrs=P1^0;
- sbit RW=P1^1;
- sbit dula=P2^6;
- sbit wela=P2^7;
- sbit SDA=P2^0;
- sbit SCL=P2^1;
- sbit option=P3^4;
- sbit add=P3^5;
- sbit dcen=P3^6;
- sbit beef=P2^3;
- /*****************************
- 延遲函數(shù)
- *****************************/
- void delayms(unit ms)
- {
- unit i,j;
- for(i=ms;i>0;i--)
- for(j=110;j>0;j--);
- }
- void delay()
- {
- }
- /******************************
- 初始化函數(shù)
- ******************************/
- void init()
- {
- EA=1;
- ET0=1;
- TMOD=0x01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TR0=1;
- }
- /******************************
- 蜂鳴器函數(shù)
- ******************************/
- void di()
- {
- beef=0;
- delayms(100);
- beef=1;
- }
- ///////////////////////////////////////////////////////////////////////
- // 1602模塊程序 //
- ///////////////////////////////////////////////////////////////////////
- /****************************
- 寫命令函數(shù)
- ****************************/
- void write_com(uchar com)
- {
- P0=0xff;
- P0=com;
- lcdrs=0;
- RW=0;
- delayms(5);
- lcden=1;
- delayms(5);
- lcden=0;
- }
- /****************************
- 寫數(shù)據(jù)函數(shù)
- ****************************/
- void write_data(uchar Data)
- {
- P0=0xff;
- P0=Data;
- lcdrs=1;
- RW=0;
- delayms(5);
- lcden=1;
- delayms(5);
- lcden=0;
- }
- /*****************************
- 屏幕初始化函數(shù)
- *****************************/
- void screen_init()
- {
- dula=0;
- wela=0; ///關閉數(shù)碼管
- write_com(0x38);
- write_com(0x0e);
- write_com(0x06);
- write_com(0x01);
- }
- /*****************************
- 1602顯示函數(shù)
- *****************************/
- void display(unit nian,uchar yue,uchar ri,uchar shi,uchar feng,uchar miao) //此函數(shù)的形參變化由中斷函數(shù)提供
- {
- screen_init();
- write_com(0x80);
- write_data(nian/1000+0x30);
- write_data(nian/100%10+0x30);
- write_data(nian%100/10+0x30);
- write_data(nian%10+0x30);
- write_data('-');
- write_data(yue/10+0x30);
- write_data(yue%10+0x30);
- write_data('-');
- write_data(ri/10+0x30);
- write_data(ri%10+0x30);
- write_com(0x80+0x40);
- write_data(shi/10+0x30);
- write_data(shi%10+0x30);
- write_data('-');
- write_data(feng/10+0x30);
- write_data(feng%10+0x30);
- write_data('-');
- write_data(miao/10+0x30);
- write_data(miao%10+0x30);
- }
- //////////////////////////////////////////////////////////////////////////////////////
- // AT24C02模塊程序 //
- //////////////////////////////////////////////////////////////////////////////////////
- /*****************************
- 啟動信號函數(shù)
- *****************************/
- void start()
- {
- SDA=1;
- delay();
- SCL=1;
- delay();
- SDA=0;
- delay();
- }
- /*****************************
- 終止信號函數(shù)
- *****************************/
- void stop()
- {
- SDA=0;
- delay();
- SCL=1;
- delay();
- SDA=1;
- delay();
- }
- /*****************************
- 應答函數(shù)
- *****************************/
- void response()
- {
- unit i;
- SCL=1;
- delay();
- while((SDA==1)&&(i<255))
- i++;
- SCL=0;
- delay();
- }
- /*****************************
- 寫一字節(jié)函數(shù)
- *****************************/
- void write_byte(uchar Data)
- {
- uchar temp;
- uchar i;
- temp=Data;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- SCL=0;
- delay();
- SDA=CY;
- delay();
- SCL=1;
- delay();
- }
- SCL=0;
- delay();
- SDA=1;
- delay();
- }
- /****************************
- 讀一字節(jié)函數(shù)
- ****************************/
- 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();
- }
- delay();
- return k;
- }
- /*****************************
- 寫操作方式函數(shù)
- *****************************/
- void write_add(uchar address,uchar Data)
- {
- start();
- write_byte(0xa0);
- response();
- write_byte(address);
- response();
- write_byte(Data);
- response();
- stop();
- }
- /*****************************
- 讀操作方式函數(shù)
- *****************************/
- uchar read_add(uchar address)
- {
- uchar Data;
- start();
- write_byte(0xa0);
- response();
- write_byte(address);
- response();
- start();
- write_byte(0xa1);
- response();
- Data=read_byte();
- stop();
- return Data;
- }
- ////////////////////////////////////////////////////////////////////////////
- // 鍵盤功能程序 //
- ////////////////////////////////////////////////////////////////////////////
- void keyscan()
- {
- if(option==0)
- {
- TR0=0;
- delayms(10);
- if(option==0) //檢測功能鍵是否按下
- {
- di();
- number++;
- while(!option);
- if(number==1)
- {
- write_com(0x80+4); //光標定義到年位置
-
- }
- if(number==2)
- {
- write_com(0x80+7);
- }
- if(number==3)
- {
- write_com(0x80+10);
- }
- if(number==4)
- {
- write_com(0x80+0x40+2);
- }
- if(number==5)
- {
- write_com(0x80+0x40+5);
- }
- if(number==6)
- {
- write_com(0x80+0x40+8);
- }
-
- }
- }
- if(number!=0) //如果按下了功能鍵 以下是功能鍵次數(shù)
- {
- if(add==0)
- {
- delayms(10);
- if(add==0)
- {
- while(!add);
- di();
- if(number==1)
- {
- nian++;
- }
- if(number==2)
- {
- yue++;
- }
- if(number==3)
- {
- ri++;
- }
- if(number==4)
- {
- shi++;
- }
- if(number==5)
- {
- feng++;
- }
- if(number==6)
- {
- miao++;
- }
- }
- }
-
- if(dcen==0)
- {
- delayms(10);
- if(dcen==0)
- {
- while(!dcen);
- di();
- if(number==1)
- {
- nian--;
- }
- if(number==2)
- {
- yue--;
- }
- if(number==3)
- {
- ri--;
- }
- if(number==4)
- {
- shi--;
- }
- if(number==5)
- {
- feng--;
- }
- if(number==6)
- {
- miao--;
- }
- }
- }
- }
- TR0=1;
- }
-
- ////////////////////////////////////////////////////////
- /// 主函數(shù) /////
- ////////////////////////////////////////////////////////
- void main()
- {
- init();
- nian=read_add(1);
- yue=read_add(2);
- ri=read_add(3);
- shi=read_add(4);
- feng=read_add(5);
- miao=read_add(6);
- while(1)
- {
-
- display(nian,yue,ri,shi,feng,miao); //接收到數(shù)據(jù)后在1602上顯示
-
- keyscan(); //對日期時間的調整,同時注意對日期進行調整的時候是不允許進入中斷的
- //接收到數(shù)據(jù)顯示完,而且更改完了之后就把數(shù)據(jù)寫入內存中,以方便以后斷電保存
-
-
-
-
-
- write_add(1,nian);
- write_add(2,yue);
- write_add(3,ri);
- write_add(4,shi); //剛才顯示時15,因為直接寫21會默認你為int,記住要復位重燒也不會改變數(shù)據(jù)
- write_add(5,feng);
- write_add(6,miao);
- }
- }
- /***************************
- 定時器中斷函數(shù)
- ****************************/
- void ser()interrupt 1
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- num++;
-
- if(num>=20)
- {
- miao++;
- num=0;
-
- }
- if(miao==60)
- {
- feng++;
- miao=0;
- }
- if(feng==60)
- {
- feng=0;
- shi++;
-
- }
- if(shi==24)
- {
- shi=0;
- ri++;
-
- }
- if(ri==30)
- {
- ri=0;
- yue++;
- }
- if(yue==12)
- {
- yue=0;
- nian++;
- }
-
- }
復制代碼
|