本電子鐘已經(jīng)全部測試OK,帶鬧鐘功能,年月日時(shí)分秒星期溫度,四個(gè)按鍵可設(shè)置鬧鐘調(diào)節(jié)時(shí)間,溫度可以顯示正125度到負(fù)的55度之間,時(shí)間走時(shí)的話,我測試了一個(gè)月,誤差不到1分鐘。本人已經(jīng)錄制成視頻,視頻里面有詳細(xì)的介紹,感興趣的可以看看 。視頻及多圖還有源代碼的地址: http://www.zg4o1577.cn/bbs/dpj-26057-1.html
程序:
#include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit rs=P1^0;//寄存器選擇 sbit rw=P1^1;//讀寫信號(hào)線 sbit lcden=P1^2;//led使能端 sbit scl=P1^3;//時(shí)鐘線 sbit rst=P1^5;//復(fù)位線 sbit io=P1^4;//數(shù)據(jù)口 sbit key_set_time=P3^4;//設(shè)置時(shí)間鍵 sbit key_add=P3^5;//加鍵 sbit key_minus=P3^6;//減鍵 sbit key_set_alarm=P3^7;//設(shè)置鬧鐘鍵 sbit bee=P1^6;//蜂鳴器接口 sbit dq=P1^7;//ds18b20測溫 uchar getTimebuf[7];//存放時(shí)間數(shù)據(jù) uchar time[]={" : : "};//時(shí)間格式字符串 uchar date[]={"20 - - "};//日期格式字符串 uchar weeklist[]={"SunMonTueWedThuFriSat"};//星期字符列表 uchar week[]={" "};//星期格式字符串 int count;//設(shè)定秒分時(shí)日月星期年的時(shí)候count的值分別為1235647 int alarm;//是否進(jìn)入鬧鐘設(shè)置界面 123分別代表開關(guān) 分 小時(shí)的設(shè)置 int isOpen;//鬧鐘是否開啟 默認(rèn)不開啟 int fen,shi;//鬧鐘的分鐘小時(shí) int isRing;//鬧鐘是否在響 uchar isInit_1302;//是否初始化時(shí)鐘完畢 int num; int temperature;//溫度 int temp_flag;//溫度正負(fù)標(biāo)志 void delay(uint x){ int y; while(x--){ for(y=100;y>0;y--); } } void write_1602com(uchar com){ //1602寫指令 rs=0; lcden=0; P2=com; delay(5); lcden=1; delay(5); lcden=0; } void write_1602data(uchar dat){ //1602寫數(shù)據(jù) rs=1; lcden=0; P2=dat; delay(5); lcden=1; delay(5); lcden=0; } void init_1602(){ //初始化1602液晶 rw=0; lcden=0; write_1602com(0x38);//設(shè)置顯示模式 write_1602com(0x0c);//顯示開關(guān)及光標(biāo)是否顯示和閃動(dòng) write_1602com(0x06);//光標(biāo)移動(dòng)方向 write_1602com(0x01);//清屏 } void write_ds1302_byte(uchar temp){ //ds1302寫一個(gè)字節(jié)數(shù)據(jù) uchar i; for(i=0;i<8;i++){ io=temp&0x01;//將數(shù)據(jù)放到IO口上 scl=0;//scl為低時(shí)準(zhǔn)備數(shù)據(jù) scl=1;//上升沿寫入 temp>>=1; } } void write_ds1302(uchar add,uchar dat){ //向地址add寫入數(shù)據(jù)dat rst=0; scl=0; rst=1; write_ds1302_byte(add); write_ds1302_byte(dat); scl=1; rst=0; } uchar read_ds1302(uchar add){ //ds1302讀數(shù)據(jù) uchar i,dat; rst=0; scl=0; rst=1; write_ds1302_byte(add);//首先寫入要讀的數(shù)據(jù)處的地址 for(i=0;i<8;i++){ if(io==1){ dat|=0x80; } scl=1; scl=0;//下降沿讀取數(shù)據(jù) dat>>=1; } scl=1; rst=0; return dat; } void read_time(uchar curr_time[]){ uchar i; uchar ucAddr = 0x81; for (i=0;i<7;i++){ curr_time[i] = read_ds1302(ucAddr);//格式為: 秒 分 時(shí) 日 月 星期 年 ucAddr += 2; } } void set_time(uchar *pSecDa){ //設(shè)定時(shí)間 uchar i; uchar ucAddr = 0x80; write_ds1302(0x8e,0x00); for(i =7;i>0;i--){ write_ds1302(ucAddr,*pSecDa); //秒 分 時(shí) 日 月 星期 年 pSecDa++; ucAddr+=2; } write_ds1302(0x8e,0x80); } void init_ds1302(){ //ds1302初始化 isInit_1302=read_ds1302(0x81);//讀出時(shí)鐘狀態(tài) if(isInit_1302&0x80){//說明沒有初始化 write_ds1302(0x8e,0x00);//關(guān)閉寫保護(hù) 以后一直開著 write_ds1302(0x90,0xa5); //輔助電源充電命令 一個(gè)二極管 一個(gè)2K電阻 write_ds1302(0x80,0x00);//秒 CH置0 開啟時(shí)鐘 write_ds1302(0x82,0x59);//分 write_ds1302(0x84,0x10);//時(shí) write_ds1302(0x86,0x07);//日 write_ds1302(0x88,0x05);//月 write_ds1302(0x8a,0x04);//星期 write_ds1302(0x8c,0x14);//年 write_ds1302(0x8e,0x80); } } char int_to_char(int temp){ //把0到9對(duì)應(yīng)的數(shù)字轉(zhuǎn)為字符 char x='0'; switch(temp){ case 0:x='0';break; case 1:x='1';break; case 2:x='2';break; case 3:x='3';break; case 4:x='4';break; case 5:x='5';break; case 6:x='6';break; case 7:x='7';break; case 8:x='8';break; case 9:x='9';break; } return x; } int ds18b20_read_temp(); void display(){ uchar bai,shi,ge,point,fuhao; read_time(getTimebuf);//時(shí)時(shí)讀取時(shí)間 time[6]=(getTimebuf[0])/16+48;//格式化時(shí)間秒 time[7]=(getTimebuf[0])%16+48; time[3]=(getTimebuf[1])/16+48;//格式化時(shí)間分 time[4]=(getTimebuf[1])%16+48; time[0]=(getTimebuf[2])/16+48;//格式化時(shí)間小時(shí) time[1]=(getTimebuf[2])%16+48; date[8]=getTimebuf[3]/16+48;//格式化日期日 date[9]=getTimebuf[3]%16+48; date[5]=getTimebuf[4]/16+48;//格式化日期月 date[6]=getTimebuf[4]%16+48; date[2]=getTimebuf[6]/16+48;//格式化日期年 date[3]=getTimebuf[6]%16+48; week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期 week[1]=weeklist[(getTimebuf[5]%10)*3+1]; week[2]=weeklist[(getTimebuf[5]%10)*3+2]; write_1602com(0x80+1); for(num=0;num<10;num++){ write_1602data(date[num]); } write_1602data(' '); for(num=0;num<3;num++){ write_1602data(week[num]); } write_1602com(0x80+0x40); for(num=0;num<8;num++){ write_1602data(time[num]); } //顯示溫度值 write_1602com(0x80+0x40+8);//設(shè)置數(shù)據(jù)指針 temperature=ds18b20_read_temp(); bai=temperature/1000+0x30; shi=temperature%1000/100+0x30; ge=temperature%100/10+0x30; point=temperature%100%10+0x30; if(temp_flag==1){//說明為正數(shù) 不顯示符號(hào)位 125.6 25.7兩種 fuhao=0x20;//顯示空白 if(bai==0x30){ bai=0x20;//如果百位為0 不顯示 if(shi==0x30){ shi=0x20;//如果百位為0 十位也為0 都不顯示 } } write_1602data(fuhao); write_1602data(bai); write_1602data(shi); }else{ fuhao=0x2d;//顯示負(fù)號(hào) -2.5 -25.8兩種 write_1602data(0x20);//因?yàn)樨?fù)數(shù)最低到55,所以不顯示百位 if(shi==0x30){ write_1602data(0x20); write_1602data(fuhao); }else{ write_1602data(fuhao); write_1602data(shi); } } write_1602data(ge); write_1602data('.'); write_1602data(point); write_1602data(0xdf); write_1602data('C'); } void display_alarm(uchar add,int dat){ //把設(shè)定的時(shí)分顯示出來 int x,y; x=dat/10; y=dat%10; write_1602com(add); write_1602data(int_to_char(x)); write_1602com(add+1);//防止寫后地址自動(dòng)向后加一 光標(biāo)閃爍看不到 write_1602data(int_to_char(y)); write_1602com(add+1); } void init_alarm(){ //鬧鐘設(shè)置界面 只有首次進(jìn)入才執(zhí)行 uchar code x[]="SET ALARM"; uchar i; if(alarm==0){ write_1602com(0x01);//清屏 write_1602com(0x80+3);//設(shè)置數(shù)據(jù)指針 for(i=0;i<9;i++){ write_1602data(x[i]); } display_alarm(0x80+0x40+5,shi);//載入鬧鐘的時(shí)分 write_1602com(0x80+0x40+7); write_1602data(':'); display_alarm(0x80+0x40+8,fen); if(isOpen){//初始化的時(shí)候如果已經(jīng)設(shè)定鬧鐘則顯示ON write_1602com(0x80+0x40+13); write_1602data(' '); write_1602data('O'); write_1602data('N'); }else{ write_1602com(0x80+0x40+13); write_1602data('O'); write_1602data('F'); write_1602data('F'); } } } void key_scan(){ int i; uchar code tips1[]="SET SUCCESS";//鬧鐘設(shè)置成功的提示 uchar code tips2[]="CANCEL SUCCESS";//取消鬧鐘的提示 if(key_set_time==0){//檢測是否按下 delay(10);//消抖 if(key_set_time==0){//再次檢測是否按下 while(!key_set_time);//檢測是否松開 delay(10);//延時(shí)消抖 while(!key_set_time);//再次檢測是否松開 if(alarm==0){//當(dāng)沒有顯示鬧鐘界面時(shí)才顯示時(shí)間設(shè)定 count++; write_ds1302(0x80,0x80);//讓時(shí)鐘停止 if(count==8){ //繼續(xù)走時(shí),說明時(shí)間已經(jīng)設(shè)定好了 write_1602com(0x0c);//讓光標(biāo)消失 write_ds1302(0x80,0);//讓時(shí)鐘繼續(xù) set_time(getTimebuf);//寫入新的時(shí)間 count=0; return; } switch(count){ case 1: write_1602com(0x80+0x40+7);//在秒的位置 break; case 2: write_1602com(0x80+0x40+4);//在分的位置 break; case 3: write_1602com(0x80+0x40+1);//在時(shí)的位置 break; case 4: write_1602com(0x80+14);//在星期的位置 break; case 5: write_1602com(0x80+10);//在日的位置 break; case 6: write_1602com(0x80+7);//在月的位置 break; case 7: write_1602com(0x80+4);//在年的位置 break; } write_1602com(0x0f);//讓光標(biāo)閃爍 } } } if(key_add==0){//檢測是否按下 delay(10);//消抖 if(key_add==0){//再次檢測是否按下 while(!key_add);//檢測是否松開 delay(10);//延時(shí)消抖 while(!key_add);//再次檢測是否松開 if(count!=0){ switch(count){ case 1: //在秒的位置 getTimebuf[0]++; if(getTimebuf[0]==0x5a){ getTimebuf[0]=0; } if(getTimebuf[0]==0x4a){ getTimebuf[0]=0x50; } if(getTimebuf[0]==0x3a){ getTimebuf[0]=0x40; } if(getTimebuf[0]==0x2a){ getTimebuf[0]=0x30; } if(getTimebuf[0]==0x1a){ getTimebuf[0]=0x20; } if(getTimebuf[0]==0x0a){ getTimebuf[0]=0x10; } time[6]=(getTimebuf[0])/16+48;//格式化時(shí)間秒 time[7]=(getTimebuf[0])%16+48; write_1602com(0x80+0x40+6);//在秒的位置 write_1602data(time[6]); write_1602com(0x80+0x40+7);//在秒的位置 write_1602data(time[7]); write_1602com(0x80+0x40+7);//讓光標(biāo)在秒的位置閃爍 break; case 2: //在分的位置 getTimebuf[1]++; if(getTimebuf[1]==0x5a){ getTimebuf[1]=0; } if(getTimebuf[1]==0x4a){ getTimebuf[1]=0x50; } if(getTimebuf[1]==0x3a){ getTimebuf[1]=0x40; } if(getTimebuf[1]==0x2a){ getTimebuf[1]=0x30; } if(getTimebuf[1]==0x1a){ getTimebuf[1]=0x20; } if(getTimebuf[1]==0x0a){ getTimebuf[1]=0x10; } time[3]=(getTimebuf[1])/16+48;//格式化時(shí)間分 time[4]=(getTimebuf[1])%16+48; write_1602com(0x80+0x40+3);//在分的位置 write_1602data(time[3]); write_1602com(0x80+0x40+4);//在分的位置 write_1602data(time[4]); write_1602com(0x80+0x40+4);//讓光標(biāo)在分的位置閃爍 break; case 3: //在時(shí)的位置 getTimebuf[2]++; if(getTimebuf[2]==0x24){ getTimebuf[2]=0; } if(getTimebuf[2]==0x1a){ getTimebuf[2]=0x20; } if(getTimebuf[2]==0x0a){ getTimebuf[2]=0x10; } time[0]=(getTimebuf[2])/16+48;//格式化時(shí)間小時(shí) time[1]=(getTimebuf[2])%16+48; write_1602com(0x80+0x40+0);//在小時(shí)的位置 write_1602data(time[0]); write_1602com(0x80+0x40+1); write_1602data(time[1]); write_1602com(0x80+0x40+1); break; case 4: //在星期的位置 getTimebuf[5]++; if(getTimebuf[5]==0x08){ getTimebuf[5]=0x01; } if((getTimebuf[5]%10)*3==21){//輪完了 重新開始 week[0]=weeklist[0]; week[1]=weeklist[1]; week[2]=weeklist[2]; }else{ week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期 week[1]=weeklist[(getTimebuf[5]%10)*3+1]; week[2]=weeklist[(getTimebuf[5]%10)*3+2]; } write_1602com(0x80+12); write_1602data(week[0]); write_1602com(0x80+13); write_1602data(week[1]); write_1602com(0x80+14); write_1602data(week[2]); write_1602com(0x80+14); break; case 5: //在日的位置 getTimebuf[3]++; if(getTimebuf[3]==0x32){ getTimebuf[3]=0x01; } if(getTimebuf[3]==0x2a){ getTimebuf[3]=0x30; } if(getTimebuf[3]==0x1a){ getTimebuf[3]=0x20; } if(getTimebuf[3]==0x0a){ getTimebuf[3]=0x10; } date[8]=(getTimebuf[3])/16+48; date[9]=(getTimebuf[3])%16+48; write_1602com(0x80+9); write_1602data(date[8]); write_1602com(0x80+10); write_1602data(date[9]); write_1602com(0x80+10); break; case 6: //在月的位置 getTimebuf[4]++; if(getTimebuf[4]==0x13){ getTimebuf[4]=0x01; } if(getTimebuf[4]==0x0a){ getTimebuf[4]=0x10; } date[5]=(getTimebuf[4])/16+48; date[6]=(getTimebuf[4])%16+48; write_1602com(0x80+6); write_1602data(date[5]); write_1602com(0x80+7); write_1602data(date[6]); write_1602com(0x80+7); break; case 7: //在年的位置 getTimebuf[6]++; if(getTimebuf[6]==0x9a){ getTimebuf[6]=0x00; } if(getTimebuf[6]==0x8a){ getTimebuf[6]=0x90; } if(getTimebuf[6]==0x7a){ getTimebuf[6]=0x80; } if(getTimebuf[6]==0x6a){ getTimebuf[6]=0x70; } if(getTimebuf[6]==0x5a){ getTimebuf[6]=0x60; } if(getTimebuf[6]==0x4a){ getTimebuf[6]=0x50; } if(getTimebuf[6]==0x3a){ getTimebuf[6]=0x40; } if(getTimebuf[6]==0x2a){ getTimebuf[6]=0x30; } if(getTimebuf[6]==0x1a){ getTimebuf[6]=0x20; } if(getTimebuf[6]==0x0a){ getTimebuf[6]=0x10; } date[2]=(getTimebuf[6])/16+48; date[3]=(getTimebuf[6])%16+48; write_1602com(0x80+3); write_1602data(date[2]); write_1602com(0x80+4); write_1602data(date[3]); write_1602com(0x80+4); break; } } if(alarm!=0){ switch(alarm){ case 1: //調(diào)節(jié)鬧鐘的開與關(guān) if(isOpen==0){ isOpen=1; write_1602com(0x80+0x40+13); write_1602data(' '); write_1602data('O'); write_1602data('N'); }else{ isOpen=0; write_1602com(0x80+0x40+13); write_1602data('O'); write_1602data('F'); write_1602data('F'); } //防止寫后地址自動(dòng)向后加一 光標(biāo)閃爍看不到 write_1602com(0x80+0x40+15); break; case 2: //調(diào)節(jié)鬧鐘的分 fen++; if(fen==60){ fen=0; } display_alarm(0x80+0x40+8,fen); break; case 3: //調(diào)節(jié)鬧鐘的小時(shí) shi++; if(shi==24){ shi=0; } display_alarm(0x80+0x40+5,shi); break; } } } } if(key_minus==0){//檢測是否按下 delay(10);//消抖 if(key_minus==0){//再次檢測是否按下 while(!key_minus);//檢測是否松開 delay(10);//延時(shí)消抖 while(!key_minus);//再次檢測是否松開 if(count!=0){ switch(count){ case 1: //在秒的位置 getTimebuf[0]--; if(getTimebuf[0]==0xff){ getTimebuf[0]=0x59; } if(getTimebuf[0]==0x4f){ getTimebuf[0]=0x49; } if(getTimebuf[0]==0x3f){ getTimebuf[0]=0x39; } if(getTimebuf[0]==0x2f){ getTimebuf[0]=0x29; } if(getTimebuf[0]==0x1f){ getTimebuf[0]=0x19; } if(getTimebuf[0]==0x0f){ getTimebuf[0]=0x09; } time[6]=(getTimebuf[0])/16+48;//格式化時(shí)間秒 time[7]=(getTimebuf[0])%16+48; write_1602com(0x80+0x40+6);//在秒的位置 write_1602data(time[6]); write_1602com(0x80+0x40+7);//在秒的位置 write_1602data(time[7]); write_1602com(0x80+0x40+7);//讓光標(biāo)在秒的位置閃爍 break; case 2: //在分的位置 getTimebuf[1]--; if(getTimebuf[1]==0xff){ getTimebuf[1]=0x59; } if(getTimebuf[1]==0x4f){ getTimebuf[1]=0x49; } if(getTimebuf[1]==0x3f){ getTimebuf[1]=0x39; } if(getTimebuf[1]==0x2f){ getTimebuf[1]=0x29; } if(getTimebuf[1]==0x1f){ getTimebuf[1]=0x19; } if(getTimebuf[1]==0x0f){ getTimebuf[1]=0x09; } time[3]=(getTimebuf[1])/16+48;//格式化時(shí)間分 time[4]=(getTimebuf[1])%16+48; write_1602com(0x80+0x40+3);//在分的位置 write_1602data(time[3]); write_1602com(0x80+0x40+4);//在分的位置 write_1602data(time[4]); write_1602com(0x80+0x40+4);//讓光標(biāo)在分的位置閃爍 break; case 3: //在時(shí)的位置 getTimebuf[2]--; if(getTimebuf[2]==0xff){ getTimebuf[2]=0x23; } if(getTimebuf[2]==0x1f){ getTimebuf[2]=0x19; } if(getTimebuf[2]==0x0f){ getTimebuf[2]=0x09; } time[0]=(getTimebuf[2])/16+48;//格式化時(shí)間小時(shí) time[1]=(getTimebuf[2])%16+48; write_1602com(0x80+0x40+0);//在小時(shí)的位置 write_1602data(time[0]); write_1602com(0x80+0x40+1); write_1602data(time[1]); write_1602com(0x80+0x40+1); break; case 4: //在星期的位置 getTimebuf[5]--; if(getTimebuf[5]==0){ getTimebuf[5]=0x07; } if((getTimebuf[5]%10)*3==21){//輪完了 重新開始 week[0]=weeklist[0]; week[1]=weeklist[1]; week[2]=weeklist[2]; }else{ week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期 week[1]=weeklist[(getTimebuf[5]%10)*3+1]; week[2]=weeklist[(getTimebuf[5]%10)*3+2]; } write_1602com(0x80+12); write_1602data(week[0]); write_1602com(0x80+13); write_1602data(week[1]); write_1602com(0x80+14); write_1602data(week[2]); write_1602com(0x80+14); break; case 5: //在日的位置 getTimebuf[3]--; if(getTimebuf[3]==0){ getTimebuf[3]=0x31; } if(getTimebuf[3]==0x2f){ getTimebuf[3]=0x29; } if(getTimebuf[3]==0x1f){ getTimebuf[3]=0x19; } if(getTimebuf[3]==0x0f){ getTimebuf[3]=0x09; } date[8]=(getTimebuf[3])/16+48; date[9]=(getTimebuf[3])%16+48; write_1602com(0x80+9); write_1602data(date[8]); write_1602com(0x80+10); write_1602data(date[9]); write_1602com(0x80+10); break; case 6: //在月的位置 getTimebuf[4]--; if(getTimebuf[4]==0){ getTimebuf[4]=0x12; } if(getTimebuf[4]==0x0f){ getTimebuf[4]=0x09; } date[5]=(getTimebuf[4])/16+48; date[6]=(getTimebuf[4])%16+48; write_1602com(0x80+6); write_1602data(date[5]); write_1602com(0x80+7); write_1602data(date[6]); write_1602com(0x80+7); break; case 7: //在年的位置 getTimebuf[6]--; if(getTimebuf[6]==0xff){ getTimebuf[6]=0x99; } if(getTimebuf[6]==0x8f){ getTimebuf[6]=0x89; } if(getTimebuf[6]==0x7f){ getTimebuf[6]=0x79; } if(getTimebuf[6]==0x6f){ getTimebuf[6]=0x69; } if(getTimebuf[6]==0x5f){ getTimebuf[6]=0x59; } if(getTimebuf[6]==0x4f){ getTimebuf[6]=0x49; } if(getTimebuf[6]==0x3f){ getTimebuf[6]=0x39; } if(getTimebuf[6]==0x2f){ getTimebuf[6]=0x29; } if(getTimebuf[6]==0x1f){ getTimebuf[6]=0x19; } if(getTimebuf[6]==0x0f){ getTimebuf[6]=0x09; } date[2]=(getTimebuf[6])/16+48; date[3]=(getTimebuf[6])%16+48; write_1602com(0x80+3); write_1602data(date[2]); write_1602com(0x80+4); write_1602data(date[3]); write_1602com(0x80+4); break; } } if(alarm!=0){ switch(alarm){ case 1: //調(diào)節(jié)鬧鐘的開與關(guān) if(isOpen==0){ isOpen=1; write_1602com(0x80+0x40+13); write_1602data(' '); write_1602data('O'); write_1602data('N'); }else{ isOpen=0; write_1602com(0x80+0x40+13); write_1602data('O'); write_1602data('F'); write_1602data('F'); } //防止寫后地址自動(dòng)向后加一 光標(biāo)閃爍看不到 write_1602com(0x80+0x40+15); break; case 2: //調(diào)節(jié)鬧鐘的分 fen--; if(fen<0){ fen=59; } display_alarm(0x80+0x40+8,fen); break; case 3: //調(diào)節(jié)鬧鐘的小時(shí) shi--; if(shi<0){ shi=23; } display_alarm(0x80+0x40+5,shi); break; } } } } if(key_set_alarm==0){//檢測是否按下 delay(10);//消抖 if(key_set_alarm==0){//再次檢測是否按下 while(!key_set_alarm);//檢測是否松開 delay(10);//延時(shí)消抖 while(!key_set_alarm);//再次檢測是否松開 if(count==0){//時(shí)間在正常走動(dòng)的時(shí)候才能設(shè)置鬧鐘 init_alarm(); alarm++;//說明進(jìn)入鬧鐘設(shè)置界面 if(alarm==4){ alarm=0;//說明鬧鐘設(shè)置完畢 write_1602com(0x01);//清屏以便顯示時(shí)間 write_1602com(0x0c);//關(guān)閉光標(biāo) //顯示設(shè)置成功或取消的提示 if(isOpen){ write_1602com(0x80+2); for(i=0;i<11;i++){ write_1602data(tips1[i]); } }else{ write_1602com(0x80+1); for(i=0;i<14;i++){ write_1602data(tips2[i]); } } //延時(shí)2ms后清屏顯示時(shí)間 delay(2000); write_1602com(0x01); }else{ switch(alarm){ case 1: write_1602com(0x80+0x40+15); break; case 2: write_1602com(0x80+0x40+9); break; case 3: write_1602com(0x80+0x40+6); break; } write_1602com(0x0f); } } } } } void beep(){ //檢測鬧鐘 并且報(bào)警 if(time[0]==int_to_char(shi/10)&&time[1]==int_to_char(shi%10)&&time[3]==int_to_char(fen/10)&&time[4]==int_to_char(fen%10)){ isRing=1;//鬧鐘響起,此時(shí)如果進(jìn)入鬧鐘設(shè)置界面 改變時(shí)分,鬧鐘就關(guān)閉了 bee=0; delay(250); bee=1; delay(250); }else{ isRing=0;//關(guān)閉鬧鐘或者一分鐘后鬧鐘自動(dòng)關(guān)閉 bee=1; } } void delay1(int i){ while(i--); } void ds18b20_init(){ uchar x=0; dq = 1; //DQ復(fù)位 delay1(8); //稍做延時(shí) dq = 0; //單片機(jī)將DQ拉低 delay1(80); //精確延時(shí) 大于 480us dq = 1; //拉高總線 delay1(14); x=dq; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗 delay1(20); } uchar ds18b20_read(){ //讀一個(gè)字節(jié) uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { dq = 0; // 給脈沖信號(hào) dat>>=1; dq = 1; // 給脈沖信號(hào) if(dq) dat|=0x80; delay1(4); } return(dat); } void ds18b20_write(char dat){ //寫一個(gè)字節(jié) uchar i=0; for (i=8; i>0; i--) { dq = 0; dq = dat&0x01; delay1(5); dq = 1; dat>>=1; } } int ds18b20_read_temp(){ //讀取溫度 uchar low; uchar high; unsigned long tmp; float value; int t;//溫度 ds18b20_init(); ds18b20_write(0xCC); //跳過讀序列號(hào)的操作 ds18b20_write(0x44); //啟動(dòng)溫度轉(zhuǎn)換 ds18b20_init(); ds18b20_write(0xCC); //跳過讀序列號(hào)的操作 ds18b20_write(0xBE); //讀取溫度寄存器 共九個(gè) 前兩個(gè)代表溫度 low=ds18b20_read();//低八位數(shù)據(jù) high=ds18b20_read();//高八位數(shù)據(jù) tmp=high; tmp<<=8; tmp=tmp|low; //此處有正負(fù)之分 if(tmp>=63488){//ffff f000 0000 0000-->(f800) temp_flag=0; //8位全為1時(shí),加1才進(jìn)位 if((~low)==0xff){//判斷l(xiāng)ow取反加1之后是否進(jìn)位 high=(~high)+1; low=0; }else{ high=~high; low=(~low)+1; } tmp=high*256+low; }else{ temp_flag=1; } value=tmp*0.0625; t=value*10+((temp_flag==1)?+0.5:-0.5);//放大十倍輸出并四舍五入 return t; } void main(){ init_1602(); init_ds1302(); while(1){ if(isOpen){//只有開啟鬧鐘的時(shí)候才檢測 beep();//不斷檢測鬧鐘 } key_scan(); if(count==0&&alarm==0){//沒有設(shè)定時(shí)間 也沒有在鬧鐘界面的時(shí)候時(shí)間才顯示 display(); } } }