⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 数字时钟的单片机开发
💻 C
字号:
#include<REG51.h>
#include<stdio.h>
#include<DS1302.h>
#include<12864.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int

uint rd_temptr(void);
void BEEP(unsigned int time);
void delay(uint t);

sbit pressSet=P1^0;
sbit pressUp=P1^1;
sbit pressDown=P1^2;

sbit RST=P2^3;   /*LCD复位,低电平有效*/

sbit set_Alarm=P1^4;
sbit Alarm_out=P3^6;
sbit en_Alarm=P1^3;

uchar set=0;
sbit change=PSW^1;

uint sec,min,hr,day,month,year,week,mmin,mhr;
uchar sec2,min2,hr2,day2,month2,year2,week2; 

uint S1,S2,S3=0;

uchar mset,time=0;


/*-----------------------------------------------------------------------------------
功能:按键标志 
名称:press
输入:按键标志位key 
输出:无
返回:无
-------------------------------------------------------------------------------------*/
bit  press(bit key)
 {
   
	 if(!key)
	 {
	   delay(600);     /*按键防抖 */ 
	   if(!key){
	   return(1);
	   delay(6000);
       delay(6000);}
       else return(0);
	  }
	  else return(0);
  }
/*-----------------------------------------------------------------------------------
功能:闰年判断 
名称:isLeapyear
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
bit isLeapyear(void)
{
	return(year%4==0&&year%100!=0)||(year%400==0);
}
/*-----------------------------------------------------------------------------------
功能:软件延时 
名称:delay
输入:t
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void delay(uint t)
{  while(t--);  
}
/*-----------------------------------------------------------------------------------
功能:蜂鸣器控制函数
名称:BEEP
输入:time
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void BEEP(unsigned int time)
{
  Alarm_out=0;
  delay(time);
  Alarm_out=1;
}
/*-----------------------------------------------------------------------------------
功能:码字转换 
名称:BCD
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void BCD(void)
{
  sec2=16*(sec/10)+(sec%10);
  min2=16*(min/10)+(min%10);
  hr2=16*(hr/10)+(hr%10);
  day2=16*(day/10)+(day%10);
  month2=16*(month/10)+(month%10);
  year2=16*(year/10)+(year%10);
  week2=16*(week/10)+(week%10);
}
/*-----------------------------------------------------------------------------------
功能:时间显示 
名称:clockdisp
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void clockdisp(void)
	 {
	  uchar temp;	
	  uchar dispbuf[11];
	  uint temptr;
	  float Temptr;
	  rst=0;sclk=0;rst=1;
	  writeclk(BURSTT);
	  temp=readbyte(SEC)&0x7f;/*读秒,去掉最高时钟停止位*/
	  sec=(temp&0x0f)+(temp>>4)*10;/*压缩BCD码转换成十进制码*/

	  temp=readbyte(MIN);/*读分*/
	  min=(temp&0x0f)+(temp>>4)*10;

	  temp=readbyte(HR);/*读时*/
	  hr=(temp&0x0f)+(temp>>4)*10;

	  temp=readbyte(DAY);/*读日*/
	  day=(temp&0x0f)+(temp>>4)*10;
	  
	  temp=readbyte(MONTH);/*读月*/	
	  month=(temp&0x0f)+(temp>>4)*10;
	
	  temp=readbyte(YEAR);/*读年*/
	  year=(temp&0x0f)+(temp>>4)*10;

	  temp=readbyte(WEEK);/*读周*/
	  week=(temp&0x0f)+(temp>>4)*10;
      
	  temptr=rd_temptr();/*读温度,温度传感器DS18B20*/
	  if(temptr&0x8000)
	  temptr=~(temptr-1);
	  Temptr=(temptr/16)+(temptr%16)*0.0625; 
	       	
	  writelcd(0,0x0c);		
	
	   switch(S2)
	   {
	     case 0: sprintf(dispbuf,"%02d:%02d:%02d",hr,min,sec);
	             displcd(0x8b,dispbuf);	break;
	   	 case 1: sprintf(dispbuf,"%02d:%02d",mhr,mmin);
	             displcd(0x8b,dispbuf);	break;
	   	 default:break;
	   }
	   sprintf(dispbuf,"%02d",year);
	   displcd(0x81,dispbuf);

	   sprintf(dispbuf,"%02d",month);
	   displcd(0x83,dispbuf);
	   
	   sprintf(dispbuf,"%02d",day);
	   displcd(0x85,dispbuf);
	   
	   
	   sprintf(dispbuf,"%0.1f",Temptr);
	   displcd(0x94,dispbuf);

       
	    switch(week)
  	   {
		 case 1: displcd(0x92,"一");break;
		 case 2: displcd(0x92,"二");break;
		 case 3: displcd(0x92,"三");break;
		 case 4: displcd(0x92,"四");break;
		 case 5: displcd(0x92,"五");break;
		 case 6: displcd(0x92,"六");break;
	     case 7: displcd(0x92,"天");break;
		 default: break;
		}

	  }
/*-----------------------------------------------------------------------------------
功能:设置DS1302时钟 
名称:setTime
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
 void setTime(void)
{  	BCD();
    writebyte(CONT,ENABLE);    /*CLOCK BURST MODE*/
    rst=0;sclk=0;rst=1;
    writeclk(BURST);
	rst=0;
	writebyte(SEC,sec2);
	writebyte(MIN,min2);
    writebyte(HR,hr2);
    writebyte(DAY,day2);
    writebyte(MONTH,month2);
	writebyte(YEAR,year2);
	writebyte(WEEK,week2);
	writebyte(CONT,DISABLE);  /*禁止写	*/	
}

/*-----------------------------------------------------------------------------------
功能:时间设置 
名称:TimeKey
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void TimeKey(void)
{

  	if(press(pressSet))
	{		
	    delay(20000);
	    set=(set+1)%8;		

	  
	}
	else if(set)
	{	

       
		 if(press(pressUp))
		 {
		 	change=1;					
		    switch(set){
			case 1:				
				year=(year+1)%100;
				if(month==2&&!isLeapyear()&&day>28)
					day=1;
			//	clockdisp();
				delay(20000);
				break;
			case 2:				
				month=month+1;
				if(month>12)
				month=1;
				switch(month)
				{
					case 2:
						if(isLeapyear())
						{
							if(day>29)
							day=1;
						}
						else if(day>28)
							day=1;
						break;
				   case 4:
				   case 6:
				   case 9:
				   case 11:
				   		if(day>30)
							day=1;
							break;
				   default:break;
				}
			//	clockdisp();				
				delay(20000);
				break;
 			case 3:				
				day+=1;
				switch(month)
				{
					case 1:
					case 3:
					case 5:
					case 7:
					case 8:
					case 10:
					case 12:
						if(day>31)
							day=1;
						break;
					case 2:
						if(isLeapyear())
						{
							if(day>29)        /*是闰年,date>29*/
							day=1;
						}
						else if(day>28)       /*不是闰年,date>28*/
							day=1;
						break;
				     default:
					 	if(day>30)
							day=1;
						break;
				}
			//	clockdisp();
				delay(20000);
				break;
			case 4:         //week			               
				week+=1;
				if(week>7)
				week=1;
			//	clockdisp();
                delay(20000);
				break;
			case 5:
				hr=(hr+1)%24;
 		//	    clockdisp();
  			    delay(20000);
				break;
			case 6:
			    min=(min+1)%60;
  		//	    clockdisp();
  			    delay(20000);
			    break;		    
		  	case 7:
				sec=(sec+1)%60;
		//		clockdisp();
     delay(20000);
				break;	
			default:
				change=0;
				break;
			}
		  }
		  else if(press(pressDown))
		 {
		    change=1;     
		    switch(set)
			{
			case 1:
			if(year)			
				year=year-1;
			else
				year=99;
			if(month==2&&!isLeapyear()&&day>28)
					day=1;
  	//		clockdisp();
  			delay(20000);
			break;
			case 2:
			if(month>1)
				month-=1;
			else
				month=12;
            switch(month)
			{
				case 2:
					if(isLeapyear())
					{
						if(day>29)
						day=1;
					}
					else if(day>28)
						day=1;
				 break;
				 case 4:
				 case 6:
				 case 9:
				 case 11:
				            if(day>30)
							day=1;
							break;
				 default:break;
			}
	//	    clockdisp();
  			delay(20000);
			break;
			case 3:
			if(day>1)
				day-=1;
			else
				day=31;
			switch(month)
				{
					case 4:
					case 6:
					case 9:
					case 11:					
						if(day>30)
							day=30;
						break;
					case 2:
						if(isLeapyear())
						{
							if(day>29)        /*是闰年,date>29*/
							day=29;
						}
						else if(day>28)       /*不是闰年,date>28*/
							day=28;
						break;
				     default:					 	
						break;
				}
		//	clockdisp();
  			delay(20000);
			break;
            case 4:
			if(week>1)
				week-=1;
			else
				week=7;
	//		clockdisp();
  			delay(20000);
			break;
  		    case 5:
			if(hr)
				hr=hr-1;
			else
				hr=23;
 	//		clockdisp();
  			delay(20000);
			break;
			case 6:
			if(min)
				min=min-1; 
 			else
				min=59;
  	//		clockdisp();
  			delay(20000);
			break;
			case 7:
			if(sec)
				sec-=1;
			else
				sec=59;
	//		clockdisp();
  			delay(20000);
			break;
			
			default:change=0;break;
			}
		  }
	  }	  
 }
/*-----------------------------------------------------------------------------------
功能:闹钟设置 
名称:AlarmKey
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
void AlarmKey(void)
 { 
   if(press(pressSet))
	{		
	    delay(30000);
	    mset=(mset+1)%3;
        if((mset+4)>=5)
        set=mset+4;	
        else
        set=0;
	}
  	else if(mset)
	{	

       	
		 if(press(pressUp))
		 {
		 		
		    switch(mset){
			case 1:	
			        mhr=(mhr+1)%24;
 			      //  clockdisp();
  			        delay(30000);
				    break;			
				
			case 2:	
			        mmin=(mmin+1)%60;
  			       // clockdisp();
  			        delay(30000);
			        break;			
		    
			default:
				    change=0;
				    break;
			}
		  }
		  else if(press(pressDown))
		 {
		    
		    switch(mset)
			{
			case 1:	if(mhr) 
			        mhr=mhr-1;
			        else
			        mhr=23;
 			      //  clockdisp();
  		         	delay(30000);
		        	break;
			
			case 2:	if(mmin)
				    mmin=mmin-1; 
 			        else
				    mmin=59;
  			       // clockdisp();
  			        delay(30000);
			        break;
            default:change=0;break;
			}
		  }
	  }	  
 }

/*-----------------------------------------------------------------------------------
功能:主函数入口
名称:main
输入:无
输出:无
返回:无
-------------------------------------------------------------------------------------*/
 void main(void)
 {	
    delay(6000);
    RST=0;            /*LCD复位*/
    delay(6000);
    RST=1; 
    
    change=1;
	lcd();
    displcd(0x80,"20");
    displcd(0x82,"年");
    displcd(0x84,"月");
    displcd(0x86,"日");
    displcd(0x88,"时间:");
   	displcd(0x90,"星期");
    displcd(0x96,"`C");	
    displcd(0x98,"闹钟");	
	
	writebyte(CONT,ENABLE);	/*写保护*/
		if(readbyte(SEC)&0x80)
	  {
	     writebyte(SEC,0x00);	/*判定1302是否起振,若不则启动它*/

	  }
	writebyte(CONT,DISABLE);
	


    while(1)
	{  	
		clockdisp();				
        if(press(set_Alarm))
	    S2=(S2+1)%2;  
		switch(S2)
		{
		  case 0:TimeKey();displcd(0x88,"时间:");break;
		  case 1:AlarmKey();displcd(0x88,"闹钟:");break;
		  default:break;
		 }
		 
		if(change)
		{
			change=0;  
			setTime();
		}
	   if(press(en_Alarm)){
              if (S3==0)
              S3=1;
              else
              S3=0;
              }
       switch(S3){
              case 0:S3=0;displcd(0x9A,"关闭");break;
              case 1:S3=1;displcd(0x9A,"开启");break;
              default:break;
              }
       if(S3){
       if((hr==mhr)&&(min==mmin)){
       BEEP(6000);
       delay(2000);
       BEEP(3000);
       }}
       else
       Alarm_out=1;	
       
	    switch(set)/*光标位置*/
		{
		 case 1:writelcd(0,0x0e);writelcd(0,0x81);break;
		 case 2:writelcd(0,0x0e);writelcd(0,0x83);break;
		 case 3:writelcd(0,0x0e);writelcd(0,0x85);break;
		 case 4:writelcd(0,0x0e);writelcd(0,0x92);break;
		 case 5:writelcd(0,0x0e);writelcd(0,0x8b);break;
		 case 6:writelcd(0,0x0e);writelcd(0,0x8d);break;
		 case 7:writelcd(0,0x0e);writelcd(0,0x8e);break;
		 default:writelcd(0,0x0c);break;
		 } 
       
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -