萬年歷1602可調有截圖_第1頁
萬年歷1602可調有截圖_第2頁
萬年歷1602可調有截圖_第3頁
萬年歷1602可調有截圖_第4頁
萬年歷1602可調有截圖_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、/ 名稱:用 DS1302 與 1602LCD 設計的可調式電子日歷與時鐘 / 說明:本例會自動調節(jié)合法日期時間,對于星期的調節(jié)會在/ 調整年月日時自動完成,閏年問題也會自動判斷。/-#include <reg51.h> #include <string.h> #define uchar unsigned char #define uint unsigned int sbit SDA=P10; /DS1302 數據線sbit CLK=P11; /DSB1302 時鐘線sbit RST=P12; /DS1302 復位線 sbit RS=P20; /LCD 寄存器選擇sbi

2、t RW=P21; /LCD 讀/寫控制sbit EN=P22; /LCD 啟用sbit K1=P34; /選擇 sbit K2=P35; /加 sbit K3=P36; /減 sbit K4=P37; /確定uchar tCount=0; uchar dat; /定義參數/一年中每個月的天數,二月的天數由年份決定 uchar MonthsDays=31,0,31,30,31,30,31,31,30,31,30,31; /周日,周一到周六0,1-6 讀取 DS1302 時分別是 1-7 uchar *WEEK="SUN","MON","TUS&

3、quot;,"WEN","THU","FRI","SAT" /LCD 顯示緩沖 uchar LCD_DSY_BUFFER1="DATE 00-00-00 "uchar LCD_DSY_BUFFER2="TIME 00:00:00 "uchar DateTime7; /所讀取的日期時間 char Adjust_Index=-1;/當前調節(jié)的時間對象:秒,分,時,日,月,年(0,1,2,3,4,6) uchar Change_Flag="-MHDM-Y" /(

4、分,時,日,月,年) (不調節(jié)秒周) /延時,向 DS1302 寫、讀一字節(jié)以及從 DS1302 指定位置度、寫數據的程序 /延時-void DelayMS(uint x) uchar i; while(x-) for(i=0;i<120;i+); /向 DS1302 寫入一個字節(jié) void Write_A_Byte_TO_DS1302(uchar x) uchar i; for(i=0;i<8;i+) SDA=x&1;CLK=1; CLK=0; x>>=1; /從 DA1302 讀取一字節(jié)-uchar Get_A_Byte_FROM_DS1302() ucha

5、r i,b,t; for(i=0;i<8;i+) b>>=1; t=SDA;b|=t<<7;CLK=1;CLK=0; /BCD 碼轉換 return b/16*10+b%16; /從 DS1302 指定的位置讀數據-uchar Read_Data(uchar addr) uchar dat; RST=0;CLK=0;RST=1; Write_A_Byte_TO_DS1302(addr); dat=Get_A_Byte_FROM_DS1302(); CLK=1;RST=0; return dat; / 向 DS1302 某地址寫入數據-void Write_DS13

6、02(uchar addr,uchar dat) CLK=0;RST=1; Write_A_Byte_TO_DS1302(addr); Write_A_Byte_TO_DS1302(dat); CLK=0;RST=0; /-/-設置時間-void SET_DS1302() uchar i; Write_DS1302(0x8E,0x00); /寫控制字,取消寫保護 for(i=1;i<7;i+) /分時日月年依次寫入 /分的起始地址 10000010(0x82),后面續(xù)依次是時.日.月.周.年.寫入地址每次遞增 2 Write_DS1302(0x80+ 2*i,(DateTimei/10&

7、lt;<4)|(DateTimei%10); Write_DS1302(0x8E,0x80);/加保護 /-/讀取當前日期時間/-void GetTime() uchar i; for(i=0;i<7;i+) DateTimei=Read_Data(0x81+2*i); /-/1602LCD 的若干顯示控制代碼 /uchar Read_LCD_State() 讀 LCD 狀態(tài) uchar Read_LCD_State() uchar state; RS=0;RW=1;EN=1;DelayMS(1);state=P0;EN=0;DelayMS(1); return state; /v

8、oid LCD_Busy_Wait() 忙等待void LCD_Busy_Wait() while(Read_LCD_State()&0x80)=0x80); DelayMS(5); /void Write_LCD_Data(uchar dat) 向 LCD 寫數據 void Write_LCD_Data(uchar dat) LCD_Busy_Wait(); RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0; /void Write_LCD_Command(uchar cmd) 寫 LCD 指令void Write_LCD_Command(ucha

9、r cmd) LCD_Busy_Wait(); RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1);EN=0; / Void Init_LCD() LCD 初始化 void Init_LCD() Write_LCD_Command(0x38);DelayMS(1); Write_LCD_Command(0x01);DelayMS(1); Write_LCD_Command(0x06);DelayMS(1); Write_LCD_Command(0x0c);DelayMS(1); /void Set_LCD_POS(uchar P) 設置液晶顯示位置 void Set_L

10、CD_POS(uchar p) Write_LCD_Command(p|0x80); /-/在 LCD 上顯示字符串 void Display_LCD_String(uchar p,uchar *s) uchar i; Set_LCD_POS(p); for(i=0;i<16;i+) Write_LCD_Data(si); DelayMS(1); /-/日期與時間值轉換為數字字符 void Format_DateTime(uchar d,uchar *a) a0=d/10+'0'a1=d%10+'0' /-/判斷是否為閏年 uchar isLeapYear

11、(uint y) return(y%4=0&y%100!=0)|(y%400=0); /-/求自 2000.1.1 開始的任何一天是星期幾 /函數沒有通過,求出總天數后再求星期幾 /因為求總天數可能會超越 uint 的范圍 void RefreshWeekDay() uint i,d,w=5; /已知 1999.12.31 是周五 for(i=2000;i<2000+DateTime6;i+) d=isLeapYear(i)?366:365; w=(w+d)%7; d=0; for(i=1;i<DateTime4;i+) d+=MonthsDaysi; d+=DateTim

12、e3;/保存星期,06 表示星期日至周六,為了與DS1302 的星期格式匹配,返回值需要加 1 DateTime5=(w+d)%7+1; /-void DateTime_Adjust(char x) switch(Adjust_Index) case 6:/年 00-99 if(x=1&DateTime6<99) DateTime6+; if(x=-1&DateTime6>0) DateTime6-; /獲取 2 月天數 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /如果年份變化后當前月份的天數大于上限則設為上限 if

13、(DateTime3>MonthsDaysDateTime4) DateTime3=MonthsDaysDateTime4; RefreshWeekDay(); /刷新星期 break; case 4: /月 01-12 if(x=1&DateTime4<12) DateTime4+; if(x=-1&DateTime4>1) DateTime4-; /獲取 2 月天數 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /如果月份變化后當前月份的天數大于上限則設為上限 if(DateTime3>MonthsDay

14、sDateTime4) DateTime3=MonthsDaysDateTime4; RefreshWeekDay(); /刷新星期 break; case 3:/日00-28/29/30/31;調節(jié)之前首先根據年份得出該年中2月的天數 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /根據當前月份決定調節(jié)日期的上限 if(x=1&DateTime3<MonthsDaysDateTime4) DateTime3+; if(x=-1&DateTime3>0) DateTime3-; RefreshWeekDay();/刷新星

15、期 break; case 2:/時 if(x=1&DateTime2<23) DateTime2+; if(x=-1&DateTime2>0) DateTime2-; break; case 1:/分 if(x=1&DateTime1<59) DateTime1+; if(x=-1&DateTime1>0) DateTime1-; break; /-/定時器 0 每秒刷新 LCD 顯示 void T0_INT() interrupt 1 TH0=-50000/256; TL0=-50000%256; if(+tCount!=2) ret

16、urn; tCount=0; /按指定的格式生成待顯示的日期時間串 Format_DateTime(DateTime6,LCD_DSY_BUFFER1+5); Format_DateTime(DateTime4,LCD_DSY_BUFFER1+8); Format_DateTime(DateTime3,LCD_DSY_BUFFER1+11); /星期 strcpy(LCD_DSY_BUFFER1+13,WEEKDateTime5-1); /時分秒 Format_DateTime(DateTime2,LCD_DSY_BUFFER2+5); Format_DateTime(DateTime1,LC

17、D_DSY_BUFFER2+8); Format_DateTime(DateTime0,LCD_DSY_BUFFER2+11); /顯示年月日,星期,時分秒 Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2); /-鍵盤中斷(INT0)-void EX_INT0() interrupt 0 if(K1=0) /選擇調整對象(Y M D H M) while(K1=0); if(Adjust_Index=-1|Adjust_Index=1) Adjust_Index=7; Adjus

18、t_Index-; if(Adjust_Index=5) Adjust_Index=4;/跳過對星期的調節(jié) LCD_DSY_BUFFER213='' LCD_DSY_BUFFER214=Change_FlagAdjust_Index; LCD_DSY_BUFFER215='' else if(K2=0)/加 while(K2=0); DateTime_Adjust(1); else if(K3=0)/減 while(K3=0); DateTime_Adjust(-1); else if(K4=0)/確定 while(K4=0); SET_DS1302(); /將

19、調整后的時間寫入 1302 LCD_DSY_BUFFER213=' ' LCD_DSY_BUFFER214=' ' LCD_DSY_BUFFER215=' ' Adjust_Index=-1; /操作索引重設為-1,時間繼續(xù)正常顯示 /-/主程序 void main() void main() Init_LCD();/液晶初始化 IE=0x83; /允許INT0,T0中斷 IP=0x01; IT0=0x01; TMOD=0x01; TH0=-50000/256; TL0=-50000%256; TR0=1; while(1) /如果為執(zhí)行調整操作

20、則正常讀取當前時間 if(Adjust_Index=-1) GetTime(); 編譯生成的*hex程序:03000000020B6C84:0C0B6C00787FE4F6D8FD758160020BB3C1:100E000053554E004D4F4E005455530057454E001C:100C75000108000C091F001F1E1F1E1F1F1E1F1E1F:100C85001F1524FF0E00FF0E04FF0E08FF0E0CFFBC:100CA500302D30302D303020000F4A54494D45202D:100CB50030303A30303A303

21、02000013AFF081C2DF0:070CC5004D48444D2D59007C:0C0DBE00C2A1C2A28B80D2A27F017E00E5:100DCA00EF1FAA0670011E4A600BE4FDEDC394787A:050DDA0050EE0D80F752:010DDF0022F1:100E4B00E4FEEF139290D291C291EFC313FF0EBE4B:020E5B0008F09D:010E5D002272:100D7000E4FFEEC313FEA290E433FDC433333354D7:100D8000804206D291C2910FBF08E

22、7EEC4540F759E:090D9000F00AA4FFEE540F2FFF3E:010D99002237:100E5E00C292C291D292120E4B120D70D291C292C8:010E6E002261:100E6F00C291D292120E4BAF05120E4BC291C2928B:010E7F002250:100D1000E4FD7F8E120E6F7C01EC25E02480FF74D1:100D2000152CF8E6FE75F00A84C454F0FDEE75F05B:100D30000A84E5F04DFD120E6F0CBC07DC7D807F50:040

23、D40008E020E6FA2:100E3500E4FCEC25E02481FF120E5E74152CF8A667:050E4500070CBC07EDE5:010E4A002285:100E8000C2A0D2A1120DC4AC80C2A2120DC6AF0482:010E9000223F:0E0E9100120E80EF20E7F97F057E00020DCAE9:0D0E9F00AB07120E91D2A0120DBEC2A2220E:0D0EAC00AB07120E91C2A0120DBEC2A22211:100D9A007F38120EAC120DC67F01120EAC120D

24、C6B0:100DAA007F06120EAC120DC67F0C120EAC7F017EAE:040DBA0000020DCA5C:070EB900EF4480FF020EACC4:060D44008B598A5A895BFD:100D4A00120EB9E4F55CAB59AA5AA95B855C8275A7:100D5A008300120990FF120E9F120DC6055CE55C16:050D6A00C3941040E1FC:010D6F002261:100E1C00EF75F00A8424301209BDEF75F00A84E5F1:090E2C00F0243090000102

25、09CF0E:090CCD00E51B24D0FFE43407FE0E:100CD600AB07AA067C007D641209F1ED4C60047F27:100CE6000180027F00EB540370047E0180027E00C7:100CF600EF5E700FAE02AF037C017D901209F1ED3D:0A0D06004C70047F0180027F002280:100BF800755F007560059007D0E51B24D0FFE434CD:100C080007FEC3E5829FE5839E502EAF82AE831216:100C18000CD6EF7E01

26、60047F6E80027F6D8E5D8F43:100C28005EE560255EFFE55F355DFE7C007D0712B1:100C380009F18C5F8D60A380C0E4F55DF55EF583F6:100C4800758201C3E5829519E58394005013AF823C:100C580074092FF8E6255EF55EE4355DF55DA38041:0C0C6800E2E518255EF55EE4355DF55D03:010C7400225D:10082000B901047F0180027F00E51BC3946350047B:100830007E01

27、80027E00EE5F6002051BB9FF047F2F:100850007E00EE5F6002151B120CCDEF60047F1D61:100870009F405A8F1802091BB901047F0180027F33:1008800000E519C3940C50047E0180027E00EE5FE7:1008A000940140047E0180027E00EE5F6002151913:1008B000120CCDEF60047F1D80027F1C8F0B74092A:1008C0002519F8E6FFE518D39F40028F18804C12D7:1008D0000CC

28、DEF60047F1D80027F1C8F0B740925F7:1008E00019F8E6FFE518C39F50047F0180027F00DE:1008F000B901047E0180027E00EF5E60020518B936:10090000FF047F0180027F00E518D3940040047E3D:10095000EE5F603B151722B901047F0180027F0022:10096000E516C3943B50047E0180027E00EE5F607A:03000B00020A46A0:100A4600C0E0C0F0C083C082C0D075D000C0

29、00C076:100A560001C002C003C004C005C006C007758C3DB6:100A6600758AB00508E5086402704F7508007B00BA:100A76007A007940AF1B120E1C7A007943AF191227:100A86000E1C7A007946AF18120E1C7A00794FAF09:100A960017120E1C7A007952AF16120E1C7A0079C4:100AA60055AF15120E1C7A00793BE4FF120D447BFC:100AB600007A00794A7F40120D44D007D00

30、6D0054F:100AC600D004D003D002D001D000D0D0D082D083C1:050AD600D0F0D0E03279:03000300020ADB13:100ADB00C0E0C0F0C083C082C0D075D000C000C0E1:100AEB0001C002C003C004C005C006C00720B42A61:100AFB0030B4FDE53AF46005E53AB40103753A0705:100B0B00153AE53AB40503753A0475575B741C2521:100B1B003AF8E6F55875595D802C20B50730B5FDD0:100B2B007F01800820B60A30B6FD7FFF12080080D7:100B4B00755920753AFF

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論