|
- #include<reg52.h>
- #include "ds18b20.h"
- #define uchar unsigned char
- #define uint unsigned int//蜂鳴器位定義
- sbit beep = P3^3 ;//DS1302相關(guān)操作線定義
- sbit RST = P1^1 ;
- sbit SCK = P1^2 ;
- sbit SDA = P1^3 ; //按鍵定義,key1切換鍵,key2加,key3減,key4鬧鐘,年月日周
- sbit key1 = P1^4 ;
- sbit key2 = P1^5 ;
- sbit key3 = P1^6 ;
- sbit key4 = P1^7 ;
- sbit key5=P1^0;
- sbit rs=P3^6;
- sbit clk=P3^7;
- uchar i,j,mod,ledzz,flag,dot=3;flag1=1 ;//控制定時(shí)器動(dòng)態(tài)掃描數(shù)碼管的第幾位,j是定時(shí)讀取時(shí)間。mod是對(duì)key1按下次數(shù)計(jì)數(shù)。flag切換鬧鐘,日期,和周.flag1為鬧鐘標(biāo)志位
- //uchar code write_addr[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分時(shí)日月周年 寫地址
- //uchar code read_addr[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分時(shí)日月周年 讀地址
- //共陽(yáng)數(shù)碼管碼表,表示0-9和-。-表示時(shí)分秒的間隔.
- uchar bit_code[]={
- 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//數(shù)碼管位選
- uchar code LED[11] =
- {
- 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
- };
- uchar disbuf[8] =
- {
- 0x62,0xa2,0xf7,0x7a,0x28,0xf7,0x7e,0x7e
- };//定義時(shí)間日期的結(jié)構(gòu)類型
- struct time
- {
- uchar second ;
- uchar minute ;
- uchar hour ;
- // uchar week ;
- uchar day ;
- uchar month ;
- uchar year ;
- }
- current_time ;
- #define ctime current_time//定義鬧鐘的時(shí)分秒變量
- uchar asec,amin,ahour ;
- void delay(uint ms)
- {
- uchar i ;
- while(ms--)
- for(i=135;i>0;i--);
- }//滴一聲,用來(lái)按鍵伴音
- void di()
- {
- uchar i ;
- for(i=0;i<40;i++)
- {
- beep = 0 ;
- delay(1) ;
- beep = 1 ;
- delay(1) ;
- }
- }
- //滴滴,連續(xù)響兩下。用來(lái)鬧鐘提醒。
- void didi()
- {
- uchar i ;
- for(i = 2; i>0; i--)
- {
- di();
- delay(140);
- }
- }//DS1302的寫驅(qū)動(dòng),傳入?yún)?shù)為一個(gè)地址和數(shù)據(jù)
- void write(uchar addr,uchar dat)
- {
- uchar i ;
- RST = 0 ;
- SCK = 0 ;
- RST = 1 ;
- for(i=0;i<8;i++)
- {
- SCK = 0 ;
- SDA = (bit)(addr&0x01) ;
- addr >>=1 ;
- SCK = 1 ;
- }
- for(i=0;i<8;i++)
- {
- SCK = 0 ;
- SDA = (bit)(dat&0x01); //下降沿寫入,上升沿讀入
- dat >>= 1 ;
- SCK = 1 ;
- }
- RST = 0 ;
- }
- //DS1302的讀驅(qū)動(dòng),傳入?yún)?shù)為一個(gè)地址,返回參數(shù)為讀到的數(shù)據(jù)
- uchar read(uchar addr)
- {
- uchar i,dat ;
- RST = 0 ;
- SCK = 0 ;
- RST = 1 ;
- for(i=0;i<8;i++)
- {
- SCK = 0 ;
- SDA =(bit)(addr&0x01);
- addr>>=1 ;
- SCK = 1 ;
- }
- for(i=0;i<8;i++)
- {
- SCK=0 ;
- dat>>=1 ;
- if(SDA)
- dat|=0x80 ;
- SCK=1 ;
- }
-
- RST=0 ;
- dat=(dat/16*10)+(dat&0x0f);
- return dat ;
- }
- //讀取DS1302的時(shí)間和日期
- void read_time()
- {
- ctime.second = read(0x81);
- ctime.minute = read(0x83);
- ctime.hour = read(0x85);
- ctime.day = read(0x87);
- ctime.month = read(0x89);
- //ctime.week = read(0x8b);
- ctime.year = read(0x8d);
- }
- //設(shè)定時(shí)間和日期
- void set_time()
- {
- if(!flag)
- {
- write(0x8e,0x00);
- write(0x80,((ctime.second/10)<<4|(ctime.second%10)));
- write(0x82,((ctime.minute/10)<<4|(ctime.minute%10)));
- write(0x84,((ctime.hour/10)<<4|(ctime.hour%10)));
- write(0x8e,0x80);
- }
- else
- {
- write(0x8e,0x00);
- write(0x86,((ctime.day/10)<<4|(ctime.day%10)));
- write(0x88,((ctime.month/10)<<4|(ctime.month%10)));
- //write(0x8a,((ctime.week/10)<<4|(ctime.week%10)));
- write(0x8c,((ctime.year/10)<<4|(ctime.year%10)));
- write(0x8e,0x80);
- }
- flag1=1 ;
- }
- //刷新顯示緩沖區(qū)
- void refbuf()
- {
- switch(flag)
- {
- case 1 :
- disbuf[0] = LED[ctime.day%10];
- disbuf[1] = LED[ctime.day/10];
- disbuf[2] = 0xbf ; //10111111 -
- disbuf[3] = LED[ctime.month%10];
- disbuf[4] = LED[ctime.month/10];
- disbuf[5] = 0xbf ;
- disbuf[6] = LED[ctime.year%10];
- disbuf[7] = LED[ctime.year/10];
- break ;
- /*case 2 :
- disbuf[0] = 0xbf ;
- disbuf[1] = 0xbf ;
- disbuf[2] = 0xbf ;
- disbuf[3] = 0xbf ;
- disbuf[4] = LED[ctime.week] ;
- disbuf[5] = 0xbf ;
- disbuf[6] = 0xbf ;
- disbuf[7] = 0xbf ;
- break ;*/
- case 2 :
- disbuf[0] = LED[asec%10];
- disbuf[1] = LED[asec/10];
- disbuf[2] = 0xbf;
- disbuf[3] = LED[amin%10];
- disbuf[4] = LED[amin/10];
- disbuf[5] = 0xbf;
- disbuf[6] = LED[ahour%10];
- disbuf[7] = LED[ahour/10];
- break ;
- default :
- disbuf[0] = LED[ctime.second%10];
- disbuf[1] = LED[ctime.second/10];
- disbuf[2] = 0xbf;
- disbuf[3] = LED[ctime.minute%10];
- disbuf[4] = LED[ctime.minute/10];
- disbuf[5] = 0xbf;
- disbuf[6] = LED[ctime.hour%10];
- disbuf[7] = LED[ctime.hour/10];
- }
- }
- //鍵盤掃描
- void keyscan()
- {
- if(key1 == 0)
- {
- delay(5);
- if(key1 == 0)
- {
- while(!key1); //key1用來(lái)調(diào)節(jié)時(shí)間和日期、鬧鐘
- mod++;//mod標(biāo)示調(diào)節(jié)時(shí)間的時(shí)候?qū)?yīng)的閃爍位,mod=1秒位或天或鬧鐘的秒,mod=2是分位,mod=3是小時(shí)位
- di();//退出調(diào)節(jié)功能,返回正常顯示
- if(mod == 4)
- {
- set_time();
- mod = 0 ;
- }
- }
- } //調(diào)節(jié)加1
- if(key2==0)
- {
- delay(5);
- if(key2==0)
- {
- while(!key2);
- di();
- switch(mod)
- {
- case 1 :
- ctime.second++;
- if(ctime.second==60)
- ctime.second=0 ;
- break ;
- case 2 :
- ctime.minute++;
- if(ctime.minute==60)
- ctime.minute=0 ;
- break ;
- case 3 :
- ctime.hour++;
- if(ctime.hour==24)
- ctime.hour=0 ;
- break ;
- } //flag=0時(shí)默認(rèn)調(diào)節(jié)時(shí)分秒,=1時(shí)調(diào)節(jié)年月日,=2時(shí)調(diào)節(jié)周,=3時(shí)調(diào)節(jié)鬧鐘,=4時(shí)就返回正常顯示,flag又key4來(lái)控制。
- if(flag==1)
- {
- switch(mod)
- {
- case 1 :
- ctime.day++;
- if(ctime.day==32)
- ctime.day=0 ;
- break ;
- case 2 :
- ctime.month++;
- if(ctime.month==13)
- ctime.month=0 ;
- break ;
- case 3 :
- ctime.year++;
- if(ctime.year==100)
- ctime.year=0 ;
- break ;
- }
- }
- /* if(flag==2)
- {
- if(mod==1)
- {
- ctime.week++;
- if(ctime.week==8)
- ctime.week=1 ;
- }
- }*/
- if(flag==2)
- {
- switch(mod)
- {
- case 1 :
- asec++;
- if(asec==60)
- asec=0 ;
- break ;
- case 2 :
- amin++;
- if(amin==60)
- amin=0 ;
- break ;
- case 3 :
- ahour++;
- if(ahour==24)
- ahour=0 ;
- break ;
- }
- }
- }
- }//調(diào)節(jié)減1,功能與key2相似。
- if(key3==0)
- {
- delay(5);
- if(key3==0)
- {
- while(!key3);
- di();
- switch(mod)
- {
- case 1 :
- if(ctime.second==0)
- ctime.second=60 ;
- ctime.second--;
- break ;
- case 2 :
- if(ctime.minute==0)
- ctime.minute=60 ;
- ctime.minute--;
- break ;
- case 3 :
- if(ctime.hour==0)
- ctime.hour=24 ;
- ctime.hour--;
- break ;
- }
- if(flag==1)
- {
- switch(mod)
- {
- case 1 :
- if(ctime.day==0)
- ctime.day=32 ;
- ctime.day--;
- break ;
- case 2 :
- if(ctime.month==0)
- ctime.month=13 ;
- ctime.month--;
- break ;
- case 3 :
- if(ctime.year==0)
- ctime.year=100 ;
- ctime.year--;
- break ;
- }
- }
- /* if(flag==2)
- {
- if(mod==1)
- {
- if(ctime.week==1)
- ctime.week=8 ;
- ctime.week--;
- }
- } */
- if(flag==2)
- {
- switch(mod)
- {
- case 1 :
- if(asec==0)
- asec=60 ;
- asec--;
- break ;
- case 2 :
- if(amin==0)
- amin=60 ;
- amin--;
- break ;
- case 3 :
- if(ahour==0)
- ahour=24 ;
- ahour--;
- break ;
- }
- }
- }
- }
- if(key4==0)
- {
- delay(5);
- if(key4==0)
- {
- while(!key4);
- di();
- flag++;
- if(flag==3)
- {
- flag=0 ;
- flag1=1 ; //KEY4按一次顯示日期,按2次顯示鬧鐘
- }
- }
- }
- if(key5==0)
- {
- delay(5);
- if(key5==0)
- {
- while(!key5);
- di();
- TR0=0;
- //TR1=1;
- ds1820rst();
- while(key5)
- { //初始化顯示
- read_temp(); //讀取溫度
- ds1820disp();
-
- } //顯示
- //if(k==2)
- while(!key5);
- TR0=1;
-
- // EA=1;
-
- }
- }
- }
- //初始化,定時(shí)器定時(shí)3ms用來(lái)動(dòng)態(tài)掃描數(shù)碼管顯示
- void init()
- {
- TMOD = 0X11 ;
- EA = 1 ;
- TH0=(65536-3000)/256 ;
- TL0=(65536-3000)%256 ;
- TL1=0X18;
- TH1=0XFC;
- ET1=1;
- PT0=1;
- ET0 = 1 ;
- TR0 = 1 ;
-
-
- /* write(0x8e,0x00); //第一次寫DS1302芯片,不然開(kāi)始顯示亂碼,只需要初始化一次就行了,以后就屏蔽掉
- write(0x80,0X10);
- write(0x82,0X10);
- write(0x84,0X10);
- write(0x86,0x23);
- write(0x88,0x07);
- write(0x8a,0x06);
- write(0x8c,0x11);
- write(0x8e,0x80); */
- read_time();
- //每次初始化的時(shí)候都讀取時(shí)鐘芯片的時(shí)間,用來(lái)顯示。
- }
- void main()
- {
- init();
- while(1)
- {
- keyscan();
- //鬧鐘判斷,默認(rèn)響1min,同時(shí)按下key2和key3關(guān)掉鬧鐘
- if(amin==ctime.minute&&ahour==ctime.hour&&flag1)
- {
- didi();
- if((key2==0)&&(key3==0))
- {
- delay(5);
- if((key2==0)&&(key3==0))
- flag1=0 ;
- }
- }
- }
- }
- void time0() interrupt 1
- {
- static unsigned char count;
- TH0=(65536-3000)/256 ;
- TL0=(65536-3000)%256 ;
- if(i==8)
- {
- i=0 ;
- j++;
- }
- /****************************/
- count++;
- switch(dot)
- {case 3:
- dot=2;
- ledzz=0;
- rs=1;
- rs=0;
- for(;ledzz!=ctime.second;)
- {
- clk=0;
- clk=1;
- ledzz++;
- }
- ET1=1;break;
- //case 2:
- default:;
- }
- /**************************/
- //實(shí)現(xiàn)調(diào)節(jié)是閃爍的效果
- if(mod|flag)
- {
- if(j==10)
- {
- switch(mod)
- {
- case 1 :
- disbuf[0]=0xff ;
- disbuf[1]=0xff ;
- break ;
- case 2 :
- disbuf[3]=0xff ;
- disbuf[4]=0xff ;
- break ;
- case 3 :
- disbuf[6]=0xff ;
- disbuf[7]=0xff ;
- break ;
- }
- }
- }
- if(count==10) //到了0.5秒
- {
- /**************************/
- ledzz++;
- if(ledzz==60) //點(diǎn)完第59個(gè)后,復(fù)位下一個(gè)則第60個(gè)被點(diǎn)亮
- {
- ledzz=0;
- rs=1;
- rs=0;
- }
- if(ledzz!=ctime.second)
- { ledzz=0;
- rs=1;
- rs=0;
- while(ledzz!=ctime.second)
- {
- clk=0;
- clk=1;
- ledzz++;
- }
- }
- /*****************************/
- clk=1; //LED亮
- di();
- clk=0;//LED滅,下一個(gè)點(diǎn)亮
-
-
- }
- /*if(count==20) //到了一步
- {
- count=0; //秒指針清零
- //ctime.second++;
- di();
- /* for(i=0;i<8;i++) //對(duì)數(shù)碼管進(jìn)行動(dòng)態(tài)掃描
- {
- P2=(0x80>>i);
- P0=disbuf[i];
- delay(5);
- } */
- P2=(0x80>>i);
- P0=disbuf[i];
- i++;
- //3msx8x20,大約480ms從DS1302芯片讀取一下時(shí)間
- if(j==20)
- {
- j=0 ;
- refbuf();
- if(mod==0)
- read_time();
-
- }
- //TR1=1;
- }
- //}
- /********************T1*****/
- void Timer1ISR(void) interrupt 3 //定時(shí)器1中斷 定時(shí)1ms用于捉個(gè)點(diǎn)亮的時(shí)間間隔
- {
- static unsigned char count;
-
- TL1=0X18;
- TH1=0XFC;
- count++;
- if(count<62)
- {
- clk=0;
- clk=1;
- ledzz++;
- if(ledzz==60) //點(diǎn)完第59個(gè)后,復(fù)位下一個(gè)則第60個(gè)被點(diǎn)亮
- {
- ledzz=0;
- rs=1;
- rs=0;
- }
- }
- else
- {
- count=0;
- TR1=0;
- }
- }
- /***************************/
復(fù)制代碼 |
|