功能:
通过8位数码管实现实时时钟,可以设置时间,切换显示模式,显示年月日,时分秒信息;可通过按键修改信息,增加、减少、确定、取消、上一个、下一个、切换模式、设置等功能。
时分秒
年月日:
部分程序:
#include #include "MAX7221.h" #include "DS1302.h" void InitTimer0(void); //定时器T0初始化函数 void Disp(void); //时间显示函数 void SSetTime(unsigned char n,unsigned char m,unsigned char *readvalue,unsigned char *Cflag); //用户设置时间函数 void Delay(unsigned char time); //延时函数 void SDisp(unsigned char n); //设置时间,数码管闪烁函数 sbit Next=P1^0; //“下一个”按钮 sbit Pre=P1^1; //“上一个”按钮 sbit ADD=P1^2; //“增加”按钮 sbit SUB=P1^3; //“减少”按钮 sbit SET=P1^4; //“确定”按钮 sbit Cancel=P1^5; //“取消”按钮 sbit LED=P2^6; //设置指示灯 SYSTEMTIME CurrentTime; //时间日期类型 signed char DispBuf[16]; //存放时间日期的个位与十位 unsigned char DISPCODE[]={0,1,2,3,4,5,6,7,8,9,0x0A,0x0F}; //数码管显示数组,0x0A数码管显示“-”,0x0F数码管不显示 unsigned int count=1200; //用于设定时间/日期在数码管上的显示时间 unsigned char DisFlag=0; //显示标志,0位时间显示,1位日期显示 unsigned char SetFlag=0; //设置标志 void main(void) { InitTimer0(); //定时器初始化 Init_Max7221(0xFF,0x0A,0x07,0x01);//MAX7221初始化 Init_DS1302(); //DS1302初始化;注:1 Warning,由于在中断0中也调用了SetTime()函数,所以有一个警告,可忽略警告;如果你将其注释掉,会出现新的警告,因为你在DS1302中写了Init_DS1302()函数,而你没有调用;标准是一定要调用Init_DS1302()函数的 IT0=1; //设置中断INT0 EX0=1; IT1=1; //设置中断INT1 EX1=1; EA=1; LED=0; //设置指示灯为灭的状态 while(1) { Disp(); //显示时间/日期 Delay(10); } return; } //时间/日期显示函数 void Disp(void) { GetTime(&CurrentTime); //获取时间/日期 if(DisFlag==0) //判断是不是显示时间 { DispBuf[7]=(CurrentTime.Second)%10; //秒的个位 DispBuf[6]=(CurrentTime.Second)/10; //秒的十位 DispBuf[5]=10; //“-” DispBuf[4]=(CurrentTime.Minute)%10; //分的个位 DispBuf[3]=(CurrentTime.Minute)/10; //分的十位 DispBuf[2]=10; //“-” DispBuf[1]=(CurrentTime.Hour)%10; //时的个位 DispBuf[0]=(CurrentTime.Hour)/10; //时的十位 } else if(DisFlag==1) { DispBuf[7]=(CurrentTime.Day)%10; //日的个位 DispBuf[6]=(CurrentTime.Day)/10; //日的十位 DispBuf[5]=10; //“-” DispBuf[4]=(CurrentTime.Month)%10; //月的个位 DispBuf[3]=(CurrentTime.Month)/10; //月的十位 DispBuf[2]=10; //“-” DispBuf[1]=(CurrentTime.Year)%10; //年的个位 DispBuf[0]=(CurrentTime.Year)/10; //年的十位 } Wr_Max7221(0x08,DISPCODE[DispBuf[7]]); //显示秒的个位或日的个位 Wr_Max7221(0x07,DISPCODE[DispBuf[6]]); //显示秒的十位或日的十位 Wr_Max7221(0x06,DISPCODE[DispBuf[5]]); //显示“-” Wr_Max7221(0x05,DISPCODE[DispBuf[4]]); //显示分的个位或月的个位 Wr_Max7221(0x04,DISPCODE[DispBuf[3]]); //显示分的十位或月的十位 Wr_Max7221(0x03,DISPCODE[DispBuf[2]]); //显示“-” Wr_Max7221(0x02,DISPCODE[DispBuf[1]]); //显示时的个位或年的个位 Wr_Max7221(0x01,DISPCODE[DispBuf[0]]); //显示时的十位或年的十位 } //T0定时器初始化子程序 void InitTimer0(void) { TMOD=0x01; //工作方式1 TH0=(65536-50000)/256; //定时时间为0.5ms TL0=(65536-50000)%256; EA=1; //开总中断 ET0=1; //允许定时器T0中断 TR0=1; //打开定时器T0 } //T0定时器服务子程序 void Timer0(void) interrupt 1 { TR0=0; //关定时器T0 TH0=(65536-50000)/256; //重载初值 TL0=(65536-50000)%256; count--; if(count==0) //count*0.5ms定时到 { if(DisFlag==0) //如果上一个是显示时间 { DisFlag=1; //改为显示日期 count=100; //显示5s } else if(DisFlag==1) { count=1200; //显示60s DisFlag=0; //改为显示时间 } } TR0=1; //打开定时器T0 } SetFlag=0; //清除设置标志 break; //退出设置模式 } if(Next==0) n=n-1; //“下一个”按钮按下时,某数据设置位标志减1 if(n<=0) n=6; //若到达0时,回到6设置 if(Pre==0) n=n+1; //“上一个”按钮按下时,某数据设置位标志加1 if(n>=7) n=1; //若到达0时,回到6设置 if(ADD==0) m=1; //“增加”按钮按下时,设置增加标志 if(SUB==0) m=2; //“减少”按钮按下时,设置减少标志 if((Next==0)||(ADD==0)||(SUB==0)) //判断是否有“下一个”按钮或“增加”按钮或“减少”按钮按下 { Delay(50); //延时(给一定的释放按钮时间) SSetTime(n,m,readvalue,&Cflag); //进入相关的设置 } SDisp(n); //显示 m=0; //清除“增加”或“减少”标志 } LED=0; //设置完毕,关设置指示灯 count=1200; //设置完毕后,“时间”显示的60s DisFlag=0; //显示“时间” EA=1; //开总中断 } //时间日期变化子函数 void SSetTime(unsigned char n,unsigned char m,signed char *readvalue,signed char* Cflag) { if(m==1) //设置值增加 { if(n==6) //年增加 { *Cflag|=0x01; //年值变化标志 readvalue[5]=readvalue[5]+1; //年值加1 if(readvalue[5]>=100) readvalue[5]=00; //判断是否大于99,若是,将其设置为0 DispBuf[0]=readvalue[5]/10; //保存年的十位 DispBuf[1]=readvalue[5]%10; //保存年的个位 }
相关文章