万历可调有图.docx
- 文档编号:26048777
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:18
- 大小:48.49KB
万历可调有图.docx
《万历可调有图.docx》由会员分享,可在线阅读,更多相关《万历可调有图.docx(18页珍藏版)》请在冰豆网上搜索。
万历可调有图
万历(可调,有图)
————————————————————————————————作者:
————————————————————————————————日期:
//名称:
用DS1302与1602LCD设计的可调式电子日历与时钟
//说明:
本例会自动调节合法日期时间,对于星期的调节会在
//调整年月日时自动完成,闰年问题也会自动判断。
//------------------------------------------------------
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSDA=P1^0;//DS1302数据线
sbitCLK=P1^1;//DSB1302时钟线
sbitRST=P1^2;//DS1302复位线
sbitRS=P2^0;//LCD寄存器选择
sbitRW=P2^1;//LCD读/写控制
sbitEN=P2^2;//LCD启用
sbitK1=P3^4;//选择
sbitK2=P3^5;//加
sbitK3=P3^6;//减
sbitK4=P3^7;//确定
uchartCount=0;
uchardat;//定义参数
//一年中每个月的天数,二月的天数由年份决定
ucharMonthsDays[]={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显示缓冲
ucharLCD_DSY_BUFFER1[]={"DATE00-00-00"};
ucharLCD_DSY_BUFFER2[]={"TIME00:
00:
00"};
ucharDateTime[7];//所读取的日期时间
charAdjust_Index=-1;//当前调节的时间对象:
秒,分,时,日,月,年(0,1,2,3,4,6)
ucharChange_Flag[]="-MHDM-Y";
//(分,时,日,月,年)(不调节秒周)
//延时,向DS1302写、读一字节以及从DS1302指定位置度、写数据的程序
//延时---------------------------------------------------
voidDelayMS(uintx)
{
uchari;
while(x--)for(i=0;i<120;i++);
}
//向DS1302写入一个字节
voidWrite_A_Byte_TO_DS1302(ucharx)
{
uchari;
for(i=0;i<8;i++)
{
SDA=x&1;CLK=1;CLK=0;x>>=1;
}
}
//从DA1302读取一字节---------------------------------------
ucharGet_A_Byte_FROM_DS1302()
{
uchari,b,t;
for(i=0;i<8;i++)
{
b>>=1;t=SDA;b|=t<<7;CLK=1;CLK=0;
}
//BCD码转换
returnb/16*10+b%16;
}
//从DS1302指定的位置读数据--------------------------------------
ucharRead_Data(ucharaddr)
{
uchardat;
RST=0;CLK=0;RST=1;
Write_A_Byte_TO_DS1302(addr);
dat=Get_A_Byte_FROM_DS1302();
CLK=1;RST=0;
returndat;
}
//向DS1302某地址写入数据-------------------------------------------
voidWrite_DS1302(ucharaddr,uchardat)
{
CLK=0;RST=1;
Write_A_Byte_TO_DS1302(addr);
Write_A_Byte_TO_DS1302(dat);
CLK=0;RST=0;
}
//-------------------------------------------
//------设置时间-------------------------------------
voidSET_DS1302()
{
uchari;
Write_DS1302(0x8E,0x00);//写控制字,取消写保护
for(i=1;i<7;i++)//分时日月年依次写入
{
//分的起始地址10000010(0x82),后面续依次是时.日.月.周.年.写入地址每次递增2
Write_DS1302(0x80+2*i,(DateTime[i]/10<<4)|(DateTime[i]%10));}
Write_DS1302(0x8E,0x80);//加保护
}
//---------------------------------------------------
//读取当前日期时间
//---------------------------------------------------
voidGetTime()
{
uchari;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data(0x81+2*i);
}
}
//---------------------------------------------------
//1602LCD的若干显示控制代码
//ucharRead_LCD_State()读LCD状态
ucharRead_LCD_State()
{
ucharstate;
RS=0;RW=1;EN=1;DelayMS
(1);state=P0;EN=0;DelayMS
(1);
returnstate;
}
//voidLCD_Busy_Wait()忙等待
voidLCD_Busy_Wait()
{
while((Read_LCD_State()&0x80)==0x80);
DelayMS(5);
}
//voidWrite_LCD_Data(uchardat)向LCD写数据
voidWrite_LCD_Data(uchardat)
{
LCD_Busy_Wait();
RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS
(1);EN=0;
}
//voidWrite_LCD_Command(ucharcmd)写LCD指令
voidWrite_LCD_Command(ucharcmd)
{
LCD_Busy_Wait();
RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS
(1);EN=0;
}
//VoidInit_LCD()LCD初始化
voidInit_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);
}
//voidSet_LCD_POS(ucharP)设置液晶显示位置
voidSet_LCD_POS(ucharp)
{
Write_LCD_Command(p|0x80);
}
//------------------------------------------------------
//在LCD上显示字符串
voidDisplay_LCD_String(ucharp,uchar*s)
{
uchari;
Set_LCD_POS(p);
for(i=0;i<16;i++)
{
Write_LCD_Data(s[i]);DelayMS
(1);
}
}
//-----------------------------------------------------------
//日期与时间值转换为数字字符
voidFormat_DateTime(uchard,uchar*a)
{
a[0]=d/10+'0';a[1]=d%10+'0';
}
//----------------------------------------------------------
//判断是否为闰年
ucharisLeapYear(uinty)
{
return(y%4==0&y%100!
=0)||(y%400==0);
}
//-----------------------------------------------------------
//求自2000.1.1开始的任何一天是星期几
//函数没有通过,求出总天数后再求星期几
//因为求总天数可能会超越uint的范围
voidRefreshWeekDay()
{
uinti,d,w=5;
//已知1999.12.31是周五
for(i=2000;i<2000+DateTime[6];i++)
{
d=isLeapYear(i)?
366:
365;
w=(w+d)%7;
}
d=0;
for(i=1;i d+=DateTime[3]; //保存星期,0~6表示星期日至周六,为了与DS1302的星期格式匹配,返回值需要加1DateTime[5]=(w+d)%7+1; } //---------------------------------------------------------- voidDateTime_Adjust(charx) { switch(Adjust_Index) { case6: //年00-99 if(x==1&DateTime[6]<99)DateTime[6]++; if(x==-1&DateTime[6]>0)DateTime[6]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]];RefreshWeekDay(); //刷新星期 break; case4: //月01-12 if(x==1&DateTime[4]<12)DateTime[4]++; if(x==-1&DateTime[4]>1)DateTime[4]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; //如果月份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) DateTime[3]=MonthsDays[DateTime[4]]; RefreshWeekDay(); //刷新星期 break; case3: //日00-28/29/30/31;调节之前首先根据年份得出该年中2月的天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])? 29: 28; //根据当前月份决定调节日期的上限 if(x==1&DateTime[3] if(x==-1&DateTime[3]>0)DateTime[3]--; RefreshWeekDay();//刷新星期 break; case2: //时 if(x==1&DateTime[2]<23)DateTime[2]++; if(x==-1&DateTime[2]>0)DateTime[2]--; break; case1: //分 if(x==1&DateTime[1]<59)DateTime[1]++; if(x==-1&DateTime[1]>0)DateTime[1]--; break; } } //--------------------------------------------------------- //定时器0每秒刷新LCD显示 voidT0_INT()interrupt1 { TH0=-50000/256; TL0=-50000%256; if(++tCount! =2)return; tCount=0; //按指定的格式生成待显示的日期时间串 Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //星期strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]); //时分秒 Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //显示年月日,星期,时分秒 Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2); } //---键盘中断(INT0)----------------------------------------- voidEX_INT0()interrupt0 { if(K1==0)//选择调整对象(YMDHM) { while(K1==0); if(Adjust_Index==-1||Adjust_Index==1)Adjust_Index=7; Adjust_Index--; if(Adjust_Index==5)Adjust_Index=4;//跳过对星期的调节 LCD_DSY_BUFFER2[13]='['; LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; LCD_DSY_BUFFER2[15]=']'; } elseif(K2==0)//加 { while(K2==0);DateTime_Adjust (1); } elseif(K3==0)//减 { while(K3==0);DateTime_Adjust(-1); } elseif(K4==0)//确定 { while(K4==0);SET_DS1302();//将调整后的时间写入1302 LCD_DSY_BUFFER2[13]=''; LCD_DSY_BUFFER2[14]=''; LCD_DSY_BUFFER2[15]=''; Adjust_Index=-1; //操作索引重设为-1,时间继续正常显示 } } //--------------------------------------------------------------- //主程序voidmain() voidmain() { 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 : 1008400
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 万历 可调