万年历程序+电路图.docx
- 文档编号:7385395
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:15
- 大小:49.97KB
万年历程序+电路图.docx
《万年历程序+电路图.docx》由会员分享,可在线阅读,更多相关《万年历程序+电路图.docx(15页珍藏版)》请在冰豆网上搜索。
万年历程序+电路图
基于单片机的万年历系统设计
(一)顶层文件万年历.C
#include
#include"LCD1602.h"
#include"DS1302.h"
#defineucharunsignedchar
#defineuintunsignedint
sbitspeaker=P2^4;
bitkey_flag1=0,key_flag2=0;
SYSTEMTIMEadjusted;
ucharsec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchardata_alarm[7]={0};
/************键盘控制******************************/
intkey_scan()//扫描是否有键按下
{inti=0;
uinttemp;
P1=0xf0;
temp=P1;
if(temp!
=0xf0)
i=1;
else
i=0;
returni;
}
ucharkey_value()//确定按键的值
{
uintm=0,n=0,temp;
ucharvalue;
ucharv[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'};
P1=0xfe;temp=P1;if(temp!
=0xfe)m=0;
P1=0xfd;temp=P1;if(temp!
=0xfd)m=1;
P1=0xfb;temp=P1;if(temp!
=0xfb)m=2;
P1=0xf7;temp=P1;if(temp!
=0xf7)m=3;
P1=0xef;temp=P1;if(temp!
=0xef)n=0;
P1=0xdf;temp=P1;if(temp!
=0xdf)n=1;
P1=0xbf;temp=P1;if(temp!
=0xbf)n=2;
value=v[m][n];
returnvalue;
}
/***************************设置闹铃函数*******************************/
voidnaoling(void)
{
uchari=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')*10;else{data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
ucharaccording(void)
{uchark;
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1;
elsek=0;
returnk;
}
voidspeak(void)
{uinti=50;
while(i)
{speaker=0;
delay
(1);
speaker=1;
delay
(1);
i--;
}
}
voidalarm(void)
{uinti=10;
while(i)
{
speak();
delay(10);
i--;
}
}
/**************************修改时间操作********************************/
voidreset(void)
{
sec_add=0;
min_add=0;
hou_add=0;
day_add=0;
mon_add=0;
yea_add=0;
}
voidadjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case'0':
sec_add++;break;
case'1':
min_add++;break;
case'2':
hou_add++;break;
case'3':
day_add++;break;
case'4':
mon_add++;break;
case'5':
yea_add++;break;
case'b':
reset();break;
default:
break;
}
adjusted.Second+=sec_add;
adjusted.Minute+=min_add;
adjusted.Hour+=hou_add;
adjusted.Day+=day_add;
adjusted.Month+=mon_add;
adjusted.Year+=yea_add;
if(adjusted.Second>59)adjusted.Second=adjusted.Second%60;
if(adjusted.Minute>59)adjusted.Minute=adjusted.Minute%60;
if(adjusted.Hour>23)adjusted.Hour=adjusted.Hour%24;
if(adjusted.Day>31)adjusted.Day=adjusted.Day%31;
if(adjusted.Month>12)adjusted.Month=adjusted.Month%12;
if(adjusted.Year>100)adjusted.Year=adjusted.Year%100;
}
/**************************中断处理函数*********************************/
voidchanging(void)interrupt0using0//需要修改时间和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
elsekey_flag1=1;
}
voidalarming(void)interrupt3using0//需要设置闹铃或者停止设置
{
if(key_flag2)key_flag2=0;
elsekey_flag2=1;
}
/********************************主函数***********************************/
main()
{uinti;
uchar*l;
ucharp1[]="D:
",p2[]="T:
";
SYSTEMTIMET;
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602();
Initial_DS1302();
while
(1)
{write_com(0x80);
write_string(p1,2);
write_com(0xc0);
write_string(p2,2);
DS1302_GetTime(&T);
adjusted.Second=T.Second;
adjusted.Minute=T.Minute;
adjusted.Hour=T.Hour;
adjusted.Week=T.Week;
adjusted.Day=T.Day;
adjusted.Month=T.Month;
adjusted.Year=T.Year;
for(i=0;i<9;i++)
{
adjusted.DateString[i]=T.DateString[i];
adjusted.TimeString[i]=T.TimeString[i];
}
adjust();
if(key_flag2)naoling();
if(according())alarm();
DateToStr(&adjusted);
TimeToStr(&adjusted);
write_com(0x82);
write_string(adjusted.DateString,8);
write_com(0xc2);
write_string(adjusted.TimeString,8);
delay(10);
}
(二)头文件1显示模块LCD1602.H
#ifndefLCD_CHAR_1602_2009_5_9
#defineLCD_CHAR_1602_2009_5_9
#defineucharunsignedchar
#defineuintunsignedint
sbitlcdrs=P2^0;
sbitlcdrw=P2^1;
sbitlcden=P2^2;
voiddelay(uintz)//延时
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharcom)//写入指令数据到lcd
{
lcdrw=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_data(uchardate)//写入字符显示数据到lcd
{
lcdrw=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit1602()//初始化设定
{
lcdrw=0;
lcden=0;
write_com(0x3C);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
voidwrite_string(uchar*pp,uintn)
{
inti;
for(i=0;i write_data(pp[i]); } #endif (三)头文件2时钟模块DS1302.H #ifndef_REAL_TIMER_DS1302_2009_5_20_ #define_REAL_TIMER_DS1302_2003_5_20_ sbitDS1302_CLK=P2^6;//实时时钟时钟线引脚 sbitDS1302_IO=P2^7;//实时时钟数据线引脚 sbitDS1302_RST=P2^5;//实时时钟复位线引脚 sbitACC0=ACC^0; sbitACC7=ACC^7; typedefstructSYSTEM_TIME { unsignedcharSecond; unsignedcharMinute; unsignedcharHour; unsignedcharWeek; unsignedcharDay; unsignedcharMonth; unsignedcharYear; unsignedcharDateString[9];//用这两个字符串来放置读取的时间 unsignedcharTimeString[9]; }SYSTEMTIME;//定义的时间类型 #defineAM(X)X #definePM(X)(X+12)//转成24小时制 #defineDS1302_SECOND0x80 #defineDS1302_MINUTE0x82 #defineDS1302_HOUR0x84 #defineDS1302_WEEK0x8A #defineDS1302_DAY0x86 #defineDS1302_MONTH0x88 #defineDS1302_YEAR0x8C #defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏 /******内部指令**********/ voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数) { unsignedchari; ACC=d; for(i=8;i>0;i--) { DS1302_IO=ACC0; DS1302_CLK=1; DS1302_CLK=0; ACC=ACC>>1;//因为在前面已经定义了ACC0=ACC^0;以便再次利用DS1302_IO=ACC0; } } unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数) { unsignedchari; for(i=8;i>0;i--) { ACC=ACC>>1; ACC7=DS1302_IO; DS1302_CLK=1; DS1302_CLK=0; } return(ACC); } /********************************/ voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr: DS1302地址,ucData: 要写的数据 { DS1302_RST=0; DS1302_CLK=0; DS1302_RST=1; DS1302InputByte(ucAddr);//地址,命令 DS1302InputByte(ucDa);//写1Byte数据 DS1302_CLK=1; DS1302_RST=0; } unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据 { unsignedcharucData; DS1302_RST=0; DS1302_CLK=0; DS1302_RST=1; DS1302InputByte(ucAddr|0x01);//地址,命令 ucData=DS1302OutputByte();//读1Byte数据 DS1302_CLK=1; DS1302_RST=0; return(ucData); } voidDS1302_SetProtect(bitflag)//是否写保护 { if(flag) Write1302(0x8E,0x10); else Write1302(0x8E,0x00); } voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数 { DS1302_SetProtect(0); Write1302(Address,((Value/10)<<4|(Value%10)));//将十进制数转换为BCD码 }//在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式 voidDS1302_GetTime(SYSTEMTIME*Time) { unsignedcharReadValue; ReadValue=Read1302(DS1302_SECOND); Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//将BCD码转换为十进制数 ReadValue=Read1302(DS1302_MINUTE); Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); ReadValue=Read1302(DS1302_HOUR); Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); ReadValue=Read1302(DS1302_DAY); Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); ReadValue=Read1302(DS1302_WEEK); Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); ReadValue=Read1302(DS1302_MONTH); Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); ReadValue=Read1302(DS1302_YEAR); Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F); } unsignedchar*DataToBCD(SYSTEMTIME*Time) { unsignedcharD[8]; D[0]=Time->Second/10<<4+Time->Second%10; D[1]=Time->Minute/10<<4+Time->Minute%10; D[2]=Time->Hour/10<<4+Time->Hour%10; D[3]=Time->Day/10<<4+Time->Day%10; D[4]=Time->Month/10<<4+Time->Month%10; D[5]=Time->Week/10<<4+Time->Week%10; D[6]=Time->Year/10<<4+Time->Year%10; returnD; } voidDateToStr(SYSTEMTIME*Time) { //将十进制数转换为液晶显示的ASCII值 Time->DateString[0]=Time->Year/10+'0'; Time->DateString[1]=Time->Year%10+'0'; Time->DateString[2]='-'; Time->DateString[3]=Time->Month/10+'0'; Time->DateString[4]=Time->Month%10+'0'; Time->DateString[5]='-'; Time->DateString[6]=Time->Day/10+'0'; Time->DateString[7]=Time->Day%10+'0'; Time->DateString[8]='\0'; } voidTimeToStr(SYSTEMTIME*Time) { //将十进制数转换为液晶显示的ASCII值 Time->TimeString[0]=Time->Hour/10+'0'; Time->TimeString[1]=Time->Hour%10+'0'; Time->TimeString[2]=': '; Time->TimeString[3]=Time->Minute/10+'0'; Time->TimeString[4]=Time->Minute%10+'0'; Time->TimeString[5]=': '; Time->TimeString[6]=Time->Second/10+'0'; Time->TimeString[7]=Time->Second%10+'0'; Time->DateString[8]='\0'; } voidInitial_DS1302(void) { unsignedcharSecond; Second=Read1302(DS1302_SECOND); if(Second&0x80)//初始化时间 DS1302_SetTime(DS1302_SECOND,0); } voidDS1302_TimeStop(bitflag)//是否将时钟停止 { unsignedcharData; Data=Read1302(DS1302_SECOND); DS1302_SetProtect(0); if(flag) Write1302(DS1302_SECOND,Data|0x80); else Write1302(DS1302_SECOND,Data&0x7F); } #endif 附录2系统电路图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 万年历 程序 电路图
![提示](https://static.bdocx.com/images/bang_tan.gif)