#include /********************************************" />

問答

AT89C52+DS1302單片機(jī)萬年歷程序

提問者:huanglei8309242013-04-30 00:00

用液晶(1602A)顯示 要求顯示年月日 時(shí)間AM PM 星期X 能顯示的越全越好 小弟分不多,只能給這么多了,不好意思啊

最佳答案

參考程序,可以調(diào)節(jié)時(shí)間,設(shè)置鬧鐘,音樂鬧鈴 #include #include /************************************************************/ #define uchar unsigned char #define uint unsigned int #define TIME (0X10000-50000) #define FLAG 0XEF //鬧鐘標(biāo)志 /************************************************************/ //引腳連接圖 sbit CLK=P1^2; sbit RST=P1^4; sbit DAT=P1^3; sbit RS=P1^5; sbit RW=P1^6; sbit E=P1^7; sbit P32=P3^2; sbit KEY1 = P2^7; sbit KEY2 = P2^6; sbit KEY3 = P2^5; sbit KEY4 = P2^4; sbit ACC_7=ACC^7; /************************************************************/ //全局變量及常量定義 uchar i=20,j; uchar DataBuf[16] = {};//日期 uchar TimeBuf[16] = {};//時(shí)間 uchar alarm[2],time[3]; uchar code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12個(gè)月的最大日期(非閏年) //閏年月星期表 const unsigned char WeekTab[] = { (3 << 5) + 31,///1月 (6 << 5) + 29,///2月 (0 << 5) + 31,///3月 (3 << 5) + 30,///4月 (5 << 5) + 31,//5月 (1 << 5) + 30,//6月 (3 << 5) + 31,//7月 (6 << 5) + 31,//8月 (1 << 5) + 30,//9月 (4 << 5) + 31,//10月 (0 << 5) + 30,//11月 (2 << 5) + 31 //12月 }; //音律表 uint code table1[]={64260,64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217}; //發(fā)聲部分的延時(shí)時(shí)間 uchar code table2[]={0x82,1,0x81,0xf4,0xd4,0xb4,0xa4,0x94,0xe2,1,0xe1,0xd4,0xb4,0xc4,0xb4,4,0}; //鬧鐘中用的全局變量 uchar th1,tl1; /************************************************************/ //延時(shí)1ms函數(shù) delay1ms(uchar time) { uchar i,j; for(i=0;i>=1; //右移一位 CLK=0; //拉低時(shí)鐘脈沖 } } /************************************************************/ //DS1302讀取子程序 uchar DS1302_Read() { uchar i,j=0; for(i=0;i<8;i++)//循環(huán)8次 { j>>=1; //右移一位 _nop_(); //延時(shí)一指令周期 CLK=0; //拉低時(shí)鐘脈沖 _nop_(); //延時(shí)一指令周期 if(DAT) //判斷接收該位數(shù)據(jù)是否為1 j|=0x80;//該位置1 _nop_(); //延時(shí)一指令周期 CLK=1; //拉高時(shí)鐘脈沖 } return(j); //返回?cái)?shù)值 } /************************************************************/ //部分顯示數(shù)據(jù)初始化 TimeStart() { TimeBuf[0]=TimeBuf[8]=TimeBuf[9]=TimeBuf[10]=0x20; //不顯示字符 TimeBuf[2]=TimeBuf[5]=':'; //時(shí)間分隔顯示 DS1302_Write(0xc1); alarm[0]=DS1302_Read(); RST=0; DS1302_Write(0xc3); alarm[1]=DS1302_Read(); RST=0; DS1302_Write(0xc5); DataBuf[0]=DS1302_Read(); RST=0; } /************************************************************/ //讀取時(shí)間 ReadTime() { uchar i,m,n; for(m=0,i=0,n=0x85;i<7;i+=3,n-=2,m++) //連續(xù)讀取時(shí),分,秒 { DS1302_Write(n); //寫入讀取寄存器指令 time[m]=DS1302_Read(); //讀取數(shù)據(jù) RST=0; //將RST電平拉低,停止傳輸 TimeBuf[i]=time[m]/16+0x30; //將兩位數(shù)據(jù)的十位轉(zhuǎn)為字符格式 TimeBuf[i+1]=time[m]%16+0x30;//將兩位數(shù)據(jù)的個(gè)位轉(zhuǎn)為字符格式 } } /************************************************************/ //功能選擇超時(shí)定時(shí)器 time0() interrupt 1 using 1 { i--; if(i==0) { if(j!=0) j--; i=20; } TH0=TIME/256,TL0=TIME%256; } /************************************************************/ //產(chǎn)生鬧鈴音調(diào) intime1() interrupt 3 { TH1=th1,TL1=tl1; P32=!P32; } /************************************************************/ //鬧鐘顯示 void AlarmShow(void) { uchar i,j,a,b,n; ET1=1; for(j=0;j<6;j++) { i=0; while(1) { a=table2[i]; if(a==0) break; b=a&0xf; a>>=4; if(a==0) { TR1=0; goto D1; } a=((--a)<<1)/2; TH1=th1=table1[a]/256,TL1=tl1=table1[a]%256; TR1=1; D1: do { b--; for(n=0;n<3;n++) { ReadTime(); LCDShow(); P2=0xff; if(KEY4 == 1) { delay1ms(100); if(KEY4 == 1) { TR1=0; ET1=0; P32 = 1; return; } } } }while(b!=0); i++; } TR1=0; } ET1=0; } /************************************************************/ //設(shè)置日期、時(shí)間 void SetTime(void) { uchar i=0xc2,year,month,day,n; TimeBuf[6]=TimeBuf[7]=0x30; DataBuf[14]=DataBuf[15]=0x20; LCDShow(); while(1) { P0=0xe; //顯示器開、光標(biāo)開 Enable(); P0=i; //定光標(biāo) Enable(); P2=0xff; if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1)) { delay1ms(100); //延時(shí)0.1s去抖動(dòng) if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1)) { j=7; if(KEY1 == 1) { i+=3; //更改設(shè)置項(xiàng)目 if(i==0x8e) i=0xc2; else if(i>0xc5) i=0xc2; } else if(KEY2 == 1) { year=(DataBuf[4]&0xf)*10+(DataBuf[5]&0xf); //將字符格式的年份轉(zhuǎn)換為數(shù)值格式 month=(DataBuf[7]&0xf)*10+(DataBuf[8]&0xf); //將字符格式的月份轉(zhuǎn)換為數(shù)值格式 day=(DataBuf[10]&0xf)*10+(DataBuf[11]&0xf); //將字符格式的日數(shù)轉(zhuǎn)換為數(shù)值格式 if(i==0x85) //設(shè)置年份 { year++; if(year>99) year=0; if((year%4)!=0) if(month==2&&day==29) day=28; } else if(i==0x88) //設(shè)置月份 { month++; if(month>12) month=1; if(day>Day[month-1]) { day=Day[month-1]; if(month==2&&(year%4)==0) //計(jì)算是否閏年 day=29; } } else if(i==0x8b) //設(shè)置日期 { day++; if(day>Day[month-1]) { if(month==2&&(year%4)==0) //計(jì)算是否閏年 { if(day>29) day=1; } if(month!=2) day=1; } } else if(i==0xc2) //設(shè)置小時(shí) { n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf); n++; if(n>23) n=0; TimeBuf[0]=n/10+0x30; TimeBuf[1]=n%10+0x30; } else //設(shè)置分鐘 { n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf); n++; if(n>59) n=0; TimeBuf[3]=n/10+0x30; TimeBuf[4]=n%10+0x30; } DataBuf[4]=year/10+0x30; //將數(shù)值格式的日期轉(zhuǎn)換為字符形式 DataBuf[5]=year%10+0x30; DataBuf[7]=month/10+0x30; DataBuf[8]=month%10+0x30; DataBuf[10]=day/10+0x30; DataBuf[11]=day%10+0x30; LCDShow(); } else if(KEY3 == 1) //按保存退出鍵后,向DS1302寫入設(shè)置后的日期時(shí)間 { DS1302_Write(0x8c); DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf)); RST=0; DS1302_Write(0x8a); DS1302_Write(SetWeek()); RST=0; for(i=7,n=0x88;i<11;i+=3,n-=2) { DS1302_Write(n); DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf)); RST=0; } for(i=0;i<7;i+=3,n-=2) { DS1302_Write(n); DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf)); RST=0; } TR0=0; return; } else { TR0=0; return; } } } if(j==0) { TR0=0; return; } } } /************************************************************/ //設(shè)置鬧鐘 void SetAlarm(void) { uchar i,n; for(i=1;i<16;i++) { DataBuf[i]=0x20; } TimeBuf[0]=alarm[0]/16+0x30; TimeBuf[1]=(alarm[0]&0xf)+0x30; TimeBuf[3]=alarm[1]/16+0x30; TimeBuf[4]=(alarm[1]&0xf)+0x30; TimeBuf[6]=TimeBuf[7]=0x30; LCDShow(); i=0xc2; while(1) { P0=0xe; //顯示器開、光標(biāo)開 Enable(); P0=i; //定光標(biāo) Enable(); P2=0xff; if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1)) { delay1ms(100); //延時(shí)0.1s去抖動(dòng) if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1)) { j=7; if(KEY1 == 1) { i+=3; if(i>0xc5) i=0xc2; } else if(KEY2 == 1) { if(i==0xc2) { n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf); n++; if(n>23) n=0; TimeBuf[0]=n/10+0x30; TimeBuf[1]=n%10+0x30; } else { n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf); n++; if(n>59) n=0; TimeBuf[3]=n/10+0x30; TimeBuf[4]=n%10+0x30; } LCDShow(); } else if(KEY3 == 1) { DS1302_Write(0xc0); DS1302_Write((TimeBuf[0]&0xf)*16+(TimeBuf[1]&0xf)); RST=0; DS1302_Write(0xc2); DS1302_Write((TimeBuf[3]&0xf)*16+(TimeBuf[4]&0xf)); RST=0; DataBuf[0]=FLAG; DS1302_Write(0xc4); DS1302_Write(DataBuf[0]); RST=0; TR0=0; TimeStart(); return; } else { TR0=0; TimeStart(); return; } } } if(j==0) { TR0=0; TimeStart(); return; } } } /************************************************************/ //DS1302初始化程序 void DS1302_Init(void) { uchar i,n; DS1302_Write(0x8c); DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf)); RST=0; DS1302_Write(0x8a); DS1302_Write(SetWeek()); RST=0; for(i=7,n=0x88;i<11;i+=3,n-=2) { DS1302_Write(n); DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf)); RST=0; } for(i=0;i<7;i+=3,n-=2) { DS1302_Write(n); DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf)); RST=0; } } /************************************************************/ //主函數(shù) main() { IE=0x82; TMOD=0x11; DS1302_Write(0x8E); //禁止寫保護(hù) DS1302_Write(0); RST=0; P0=1; //清屏并光標(biāo)復(fù)位 Enable(); P0=0x38; //設(shè)置顯示模式:8位2行5x7點(diǎn)陣 Enable(); P0=6; //文字不動(dòng),光標(biāo)自動(dòng)右移 Enable(); DS1302_Init(); TimeStart(); while(1) { ReadTime(); //讀取時(shí)間 LCDShow(); //顯示時(shí)間 if(DataBuf[0]!=0x20) if(time[0]==alarm[0]) if(time[1]==alarm[1]) if(time[2]==0) AlarmShow(); P2=0xff; if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)) { delay1ms(100); //延時(shí)0.1s去抖動(dòng) if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)) { j=7; TH0=TIME/256,TL0=TIME%256; TR0=1; if(KEY1 == 1) { SetTime(); } else if(KEY2 == 1) { SetAlarm(); } else if(KEY3 == 1) { TR0=0; if(DataBuf[0]==FLAG) DataBuf[0]=0x20; else DataBuf[0]=FLAG; DS1302_Write(0xc4); DS1302_Write(DataBuf[0]); RST=0; } } } delay1ms(100); } }

回答者:chrisgz912016-04-30 00:00

DS 5相關(guān)問題

  • DS160照片問題,謝謝

    DS-160表上的照片只要能上傳上去,DS-160表就ok了(不過有一點(diǎn)必須是1-3個(gè)月的近照),但是你簽證的時(shí)候,你必須必須必須帶合符美領(lǐng)館要求的照片,因?yàn)樗弥掌湍惚救诉有護(hù)照上的照片對(duì)比,方便他工作,比如1-

    提問者:Juliet錚錚2013-04-18

  • 水質(zhì)t ds值是52可直飲么

    單就這一個(gè)指標(biāo)來說,如果單位是ppm。這是是符合飲用水TDS要求的。但能不能直飲,不能單純從這一個(gè)數(shù)據(jù)上判斷。

    提問者:wuli寶噠女人2016-09-18

  • 夏浦液晶電視lcd一52ds20a多少錢

    參考報(bào)價(jià):¥ 4599重要參數(shù)詳細(xì)參數(shù)>>屏幕尺寸: 52英寸分辨率: 1920*1080液晶面板: X-GEN超晶面板響應(yīng)時(shí)間: 暫無數(shù)據(jù)HDMI接口: 2*HDMIUSB媒體播放: 暫無數(shù)據(jù)最佳觀看距離: 4.1-5

    提問者:workman9182016-08-08

  • 汽車未做首保跑了高速

    磨合2000公里以后跑高速路對(duì)車沒有傷害。超車時(shí)達(dá)到150公里也不必?fù)?dān)心.時(shí)間很短也沒有多少磨損。 高速路上跑110公里既安全也不超速.用定速巡航還省油. 如果長(zhǎng)時(shí)間高檔低速或低檔高速對(duì)發(fā)動(dòng)機(jī)有傷害。短時(shí)間讓發(fā)動(dòng)機(jī)

    提問者:盧灶月99582013-03-02

  • 別克新君威首保和拉高速的問題!

    3000公里首保,6000公里二保.以后每五千公里速度上去再下來. 再上去 再下來.反復(fù)幾次就好了. 別看時(shí)速. 看轉(zhuǎn)數(shù).

    提問者:nuptwanglei2014-06-24

  • 夏普 LCD-52DS50A 和 LCD-52LX640A 有哪些區(qū)別

    DS50是網(wǎng)絡(luò)電商的專供型號(hào),功能跟540A一樣,跟640A最主要的差別就是640帶3D功能 58車>>

    提問者:yunj95112014-07-07

相關(guān)閱讀

按字母分類: