万年历(1602可调,有截图).doc_第1页
万年历(1602可调,有截图).doc_第2页
万年历(1602可调,有截图).doc_第3页
万年历(1602可调,有截图).doc_第4页
万年历(1602可调,有截图).doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/ 名称:用 DS1302 与 1602LCD 设计的可调式电子日历与时钟 / 说明:本例会自动调节合法日期时间,对于星期的调节会在/ 调整年月日时自动完成,闰年问题也会自动判断。/-#include #include #define uchar unsigned char #define uint unsigned int sbit SDA=P10; /DS1302 数据线sbit CLK=P11; /DSB1302 时钟线sbit RST=P12; /DS1302 复位线 sbit RS=P20; /LCD 寄存器选择sbit 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,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;/当前调节的时间对象:秒,分,时,日,月,年(0,1,2,3,4,6) uchar Change_Flag=-MHDM-Y; /(分,时,日,月,年) (不调节秒周) /延时,向 DS1302 写、读一字节以及从 DS1302 指定位置度、写数据的程序 /延时-void DelayMS(uint x) uchar i; while(x-) for(i=0;i120;i+); /向 DS1302 写入一个字节 void Write_A_Byte_TO_DS1302(uchar x) uchar i; for(i=0;i=1; /从 DA1302 读取一字节-uchar Get_A_Byte_FROM_DS1302() uchar i,b,t; for(i=0;i=1; t=SDA;b|=t7;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_DS1302(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;i7;i+) /分时日月年依次写入 /分的起始地址 10000010(0x82),后面续依次是时.日.月.周.年.写入地址每次递增 2 Write_DS1302(0x80+ 2*i,(DateTimei/104)|(DateTimei%10); Write_DS1302(0x8E,0x80);/加保护 /-/读取当前日期时间/-void GetTime() uchar i; for(i=0;i7;i+) DateTimei=Read_Data(0x81+2*i); /-/1602LCD 的若干显示控制代码 /uchar Read_LCD_State() 读 LCD 状态 uchar Read_LCD_State() uchar state; RS=0;RW=1;EN=1;DelayMS(1);state=P0;EN=0;DelayMS(1); return state; /void 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(uchar 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_LCD_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;i16;i+) Write_LCD_Data(si); DelayMS(1); /-/日期与时间值转换为数字字符 void Format_DateTime(uchar d,uchar *a) a0=d/10+0;a1=d%10+0; /-/判断是否为闰年 uchar isLeapYear(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;i2000+DateTime6;i+) d=isLeapYear(i)?366:365; w=(w+d)%7; d=0; for(i=1;iDateTime4;i+) d+=MonthsDaysi; d+=DateTime3;/保存星期,06 表示星期日至周六,为了与DS1302 的星期格式匹配,返回值需要加 1 DateTime5=(w+d)%7+1; /-void DateTime_Adjust(char x) switch(Adjust_Index) case 6:/年 00-99 if(x=1&DateTime60) DateTime6-; /获取 2 月天数 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime3MonthsDaysDateTime4) DateTime3=MonthsDaysDateTime4; RefreshWeekDay(); /刷新星期 break; case 4: /月 01-12 if(x=1&DateTime41) DateTime4-; /获取 2 月天数 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /如果月份变化后当前月份的天数大于上限则设为上限 if(DateTime3MonthsDaysDateTime4) DateTime3=MonthsDaysDateTime4; RefreshWeekDay(); /刷新星期 break; case 3:/日00-28/29/30/31;调节之前首先根据年份得出该年中2月的天数 MonthsDays2=isLeapYear(2000+DateTime6)?29:28; /根据当前月份决定调节日期的上限 if(x=1&DateTime30) DateTime3-; RefreshWeekDay();/刷新星期 break; case 2:/时 if(x=1&DateTime20) DateTime2-; break; case 1:/分 if(x=1&DateTime10) DateTime1-; break; /-/定时器 0 每秒刷新 LCD 显示 void T0_INT() interrupt 1 TH0=-50000/256; TL0=-50000%256; if(+tCount!=2) return; 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,LCD_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; Adjust_Index-; if(Adjust_Index=5) Adjust_Index=4;/跳过对星期的调节 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(); /将调整后的时间写入 1302 LCD_DSY_BUFFER213= ; LCD_DSY_BUFFER214= ; LCD_DSY_BUFFER215= ; Adjust_Index=-1; /操作索引重设为-1,时间继续正常显示 /-/主程序 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) /如果为执行调整操作则正常读取当前时间 if(Adjust_Index=-1) GetTime(); 编译生成的*hex程序:03000000020B6C84:0C0B6C00787FE4F6D8FD758160020BB3C1:100E000053554E004D4F4E005455530057454E001C:0C0E10005448550046524900534154001C:100C75000108000C091F001F1E1F1E1F1F1E1F1E1F:100C85001F1524FF0E00FF0E04FF0E08FF0E0CFFBC:100C95000E10FF0E14FF0E180F3B44415445203033:100CA500302D30302D303020000F4A54494D45202D:100CB50030303A30303A30302000013AFF081C2DF0:070CC5004D48444D2D59007C:0C0DBE00C2A1C2A28B80D2A27F017E00E5:100DCA00EF1FAA0670011E4A600BE4FDEDC394787A:050DDA0050EE0D80F752:010DDF0022F1:100E4B00E4FEEF139290D291C291EFC313FF0EBE4B:020E5B0008F09D:010E5D002272:100D7000E4FFEEC313FEA290E433FDC433333354D7:100D8000804206D291C2910FBF08E7EEC4540F759E:090D9000F00AA4FFEE540F2FFF3E:010D99002237:100E5E00C292C291D292120E4B120D70D291C292C8:010E6E002261:100E6F00C291D292120E4BAF05120E4BC291C2928B:010E7F002250:100D1000E4FD7F8E120E6F7C01EC25E02480FF74D1:100D2000152CF8E6FE75F00A84C454F0FDEE75F05B:100D30000A84E5F04DFD120E6F0CBC07DC7D807F50:040D40008E020E6FA2:100E3500E4FCEC25E02481FF120E5E74152CF8A667:050E4500070CBC07EDE5:010E4A002285:100E8000C2A0D2A1120DC4AC80C2A2120DC6AF0482:010E9000223F:0E0E9100120E80EF20E7F97F057E00020DCAE9:0D0E9F00AB07120E91D2A0120DBEC2A2220E:0D0EAC00AB07120E91C2A0120DBEC2A22211:100D9A007F38120EAC120DC67F01120EAC120DC6B0:100DAA007F06120EAC120DC67F0C120EAC7F017EAE:040DBA0000020DCA5C:070EB900EF4480FF020EACC4:060D44008B598A5A895BFD:100D4A00120EB9E4F55CAB59AA5AA95B855C8275A7:100D5A008300120990FF120E9F120DC6055CE55C16:050D6A00C3941040E1FC:010D6F002261:100E1C00EF75F00A8424301209BDEF75F00A84E5F1:090E2C00F024309000010209CF0E:090CCD00E51B24D0FFE43407FE0E:100CD600AB07AA067C007D641209F1ED4C60047F27:100CE6000180027F00EB540370047E0180027E00C7:100CF600EF5E700FAE02AF037C017D901209F1ED3D:0A0D06004C70047F0180027F002280:100BF800755F007560059007D0E51B24D0FFE434CD:100C080007FEC3E5829FE5839E502EAF82AE831216:100C18000CD6EF7E0160047F6E80027F6D8E5D8F43:100C28005EE560255EFFE55F355DFE7C007D0712B1:100C380009F18C5F8D60A380C0E4F55DF55EF583F6:100C4800758201C3E5829519E58394005013AF823C:100C580074092FF8E6255EF55EE4355DF55DA38041:0C0C6800E2E518255EF55EE4355DF55D03:010C7400225D:10080000A907E53A14700302095714700302091E80:100810001470030208CF14605F24FE600302098F86:10082000B901047F0180027F00E51BC3946350047B:100830007E0180027E00EE5F6002051BB9FF047F2F:100840000180027F00E51BD3940040047E018002FA:100850007E00EE5F6002151B120CCDEF60047F1D61:1008600080027F1C8F0B74092519F8E6FFE518D369:100870009F405A8F1802091BB901047F0180027F33:1008800000E519C3940C50047E0180027E00EE5FE7:1008900060020519B9FF047F0180027F00E519D3CA:1008A000940140047E0180027E00EE5F6002151913:1008B000120CCDEF60047F1D80027F1C8F0B74092A:1008C0002519F8E6FFE518D39F40028F18804C12D7:1008D0000CCDEF60047F1D80027F1C8F0B740925F7:1008E00019F8E6FFE518C39F50047F0180027F00DE:1008F000B901047E0180027E00EF5E60020518B936:10090000FF047F0180027F00E518D3940040047E3D:100910000180027E00EE5F60021518020BF8B9013B:10092000047F0180027F00E517C3941750047E0105:1009300080027E00EE5F60020517B9FF047F018030:10094000027F00E517D3940040047E0180027E0000:10095000EE5F603B151722B901047F0180027F0022:10096000E516C3943B50047E0180027E00EE5F607A:10097000020516B9FF047F0180027F00E516D394BB:100980000040047E0180027E00EE5F6002151622A8:03000B00020A46A0:100A4600C0E0C0F0C083C082C0D075D000C000C076:100A560001C002C003C004C005C006C007758C3DB6:100A6600758AB00508E5086402704F7508007B00BA:100A76007A007940AF1B120E1C7A007943AF191227:100A86000E1C7A007946AF18120E1C7A00794FAF09:100A960017120E1C7A007952AF16120E1C7A0079C4:100AA60055AF15120E1C7A00793BE4FF120D447BFC:100AB600007A00794A7F40120D44D007D006D0054F:100AC600D004D003D002D001D000D0D0D082D083C1:050AD600D0F0D0E03279:03000300020ADB13:100ADB00C0E0C0F0C083C082C0D075D000C000C0E1:100AEB0001C002C003C004C005C006C00720B42A61:100AFB0030B4FDE53AF46005E53AB40103753A0705:100B0B00153AE53AB40503753A0475575B741C2521:100B1B003AF8E6F55875595D802C20B50730B5FDD0:100B2B007F01800820B60A30B6FD7FFF12080080D7:100B3B001520B71230B7FD120D10755720755820C0:100B4B00755920753AFFD007D006D005D004D003D5:100B5B00D002D001

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论