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

📄 main.c

📁 可设置八个闹钟的智能时钟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
                            if(tmp<0) min=59;   else  min=tmp;   }
   						  break;
			   case 0xf3: if(show_status==0)          //闹钟设置的"分钟"减1
						   { tmp=alarm[cur_alarm_set].m-1;
						     if(tmp<0)    alarm[cur_alarm_set].m=59;
							 else         alarm[cur_alarm_set].m=tmp;
							}
                          else if(show_status==3)      
			               { day--;                 //当前日期的"日"减1
                             if(day==0)  day=31; }
						  else if(show_status==4)         
                           { tmp=sec-1;             //当前时间的"秒"减1
                             count_down=8000;
                             if(tmp<0) sec=59;   else  sec=tmp; }
						  break;
			   case 0xfd: if(show_status==0)			  //切换周末标志
			                 alarm_wk^=0x1<<cur_alarm_set;
						  break;
			   case 0xfe: if(show_status==0)			  //切换启用标志
			                 alarm_en^=0x1<<cur_alarm_set;
			  }       //end of switch(attr)
			 return;
}
////////////////////////////////////////////////////////////////////////
void SetAlarm()		//第一个按钮
{ 
//如果闹钟正响,按此键停止
if(sound) 
	{ 
		alarm_stop=1; 
		sound=0; 
	}   
//正显示日期或时间 进入闹钟设置	
else if((show_status==1 || show_status==2) && led_on)
	{ 
		show_status=0;  
		cur_alarm_set=0;  
		attr=0x3f; 
	} 
//如正在设置闹钟时间项  返回当前时间显示		      
else if(show_status==0) 
	{
		show_status=2; 
		new_alarm_info=1;
		attr=0xff;
	} 
}        
////////////////////////////////////////////////////////////////////////
void Timer0ISR(void) interrupt 1 using 3	//定时器0中断程序,用于走时,1/8000秒一次
{
	unsigned char tmp,tmp_days;
  	count_down--;
  if(count_down==1 || count_down==2001 || count_down==4001 || count_down==6001)
   { flash=~flash;            				//数码管闪烁的开关量
     if(sound && flash) sound_output=0;		//驱动蜂鸣器
     else             sound_output=1;		//关闭蜂鸣器
	 return;
	}

/*** 计算当前日期为星期几***/  
  if(count_down==3000)
   { if(year==0)       weekday=5;		  //2000年1月1日为星期六
    else { tmp=(year-1)/4+1;   tmp=(year-tmp)+tmp*2;
         weekday=(tmp+5)%7;           //计算出当前年的1月1日为星期几
        }
     tmp_days=0;
     for(tmp=1;tmp<month;tmp++)
       if(tmp==1 || tmp==3 || tmp==5 || tmp==7 || tmp==8 || tmp==10)
          tmp_days=tmp_days+31;
       else if(tmp==4 || tmp==6 || tmp==9 || tmp==11)
	      tmp_days=tmp_days+30;
       else if(tmp==2)
	      { if(year%4==0) tmp_days=tmp_days+29;
            else         tmp_days=tmp_days+28;
           }
     tmp_days=tmp_days+day-1;    weekday=(weekday+tmp_days%7)%7+1;
	 return;
	}
/***  查询是否有闹钟时间项符合触发条件 ***/
  if(count_down==5000)
  { if((alarm_stop || sound) && alarm[cur_alarm_active].m!=min) 	//触发后1分钟
      { alarm_stop=0; sound=0; }							//自动关蜂鸣器

    if(sound==0 && alarm_stop==0)           //没有已触发的闹钟项
     for(tmp=0;tmp<8;tmp++)				  //则查询8个闹钟项内是否有符合条件的
	  { if(((alarm_en>>tmp)&1)==0) continue;    //该闹钟项不启用
	    if(((alarm_wk>>tmp)&1)==1)           //该闹钟项周末有效
		  { if(weekday!=6 && weekday!=7) continue;  }	//当前不是星期六或星期天
		else
		  { if(weekday==6 || weekday==7) continue;  }

        if(alarm[tmp].h==hour && alarm[tmp].m==min) 	  	//比较当前时间与该
          { sound=1;  cur_alarm_active=tmp; break; }		//闹钟项的时间
	   }
    return;
   }

  if(count_down==0)  				//过了一秒钟
   { count_down=8000;
     sec++;
     if(sec==60)
      { sec=0;
        min++;
        if(min==60)
          { min=0;
            hour++;
            if(hour==24)
              { hour=0;   day++;
				switch(day)
				{ case 29: if(month==2 && year%4)    { day=1; month=3; }
				           break; 
				  case 30: if(month==2 && year%4==0) { day=1; month=3; }
				           break; 
				  case 31: if(month==4 || month==6 || month==9 || month==11)
				           { day=1; month++; }
					       break; 
				  case 32: day=1;          month++;
				         if(month==13) { month=1; year++; }
				 }
               }
           }
       }
     }
}
///////////////////////////////////////////////////////
//定时器2中断,用于按键扫描
//////////////////////////////////////////////////////
void Timer1ISR(void) interrupt 3 using 2		
{
unsigned char keytmp;
	TH1=0x15; 
	TL1=0xa0;      // 每30ms中断一次
  if(show_status==0)   //当前正在设置闹钟项
    { 
	 display[0]=dis_code[ cur_alarm_set ];               
	 display[1]=0xff;
     display[2]=dis_code[ alarm[cur_alarm_set].h/10 ];      
	 display[3]=dis_code[ alarm[cur_alarm_set].h%10 ];
	 display[4]=dis_code[ alarm[cur_alarm_set].m/10 ];      
	 display[5]=dis_code[ alarm[cur_alarm_set].m%10 ];
     display[6]=dis_code[ (alarm_wk>>cur_alarm_set)&1 ];  
	 display[7]=dis_code[ (alarm_en>>cur_alarm_set)&1 ];
     }
  if(show_status==1 || show_status==3)         //当前显示或设置日期
    { 
	  display[0]=dis_code[ year/10 ];	  
	  display[1]=dis_code[ year%10 ];	  
	  display[2]=dis_code[ month/10 ];	  
	  display[3]=dis_code[ month%10 ];   
	  display[4]=dis_code[ day/10 ];	  
	  display[5]=dis_code[ day%10 ];
	  display[6]=0xff;        
	  display[7]=dis_code[ weekday ];
     }
  if(show_status==2 || show_status==4)         //当前显示或设置时间
    { 
	display[0]=dis_code[ hour/10 ];	  
	display[1]=dis_code[ hour%10 ];
	display[2]=dis_code[ min/10 ];
 	display[3]=dis_code[ min%10 ];
	display[4]=dis_code[ sec/10 ];	  
	display[5]=dis_code[ sec%10 ];
	display[6]=0xff;  
	display[7]=0xff;  
	 }
/***  按键扫描及处理  ***/
	keytmp=P3;
	keytmp=keytmp>>2;
	keytmp=~(keytmp) & 0x0f;
  if(keytmp==0)  {km=0;kp=0;}   
  else 
   { if(km==0)   km=1;   
	 else
     { if(kp==0)
        { kp=1;
		  if(keytmp==1)		       SetAlarm();	//第一个按钮闹钟设置
		  if(keytmp==2 && led_on)  SetInc(); 	//第二个按钮,仅当数码管打开时有效
		  if(keytmp==4)		       SetReduce();	//第三个按钮
		  if(keytmp==8 & led_on)   SetNext();  	//第四个按钮,仅当数码管打开时有效 
		 }      // end of if(kp==0)
  	  }         // end of if(km==0)
   }            // end of if(keytmp!=0)
}

//////////////////////////////////////////////////////////
//主函数入口
/////////////////////////////////////////////////////////
void main(void)
{
	  unsigned char i;
	  hour=12; min=00; sec=00;  
	  year=8;  month=8;  day=8;
	  count_down=8000;
	  flash=0; attr=0xff;      
	  led_on=1;			//点亮数码管标志
	  km=0;kp=0;          
	  show_status=2;     //加电后显示当前时间
	  new_alarm_info=0;  
	  sound=0;   
	  alarm_stop=0;   
  
  for(i=0;i<8;i++)           //从EEPROM中读入8个闹钟设置
    { 
		alarm[i].h=myread(i*2);  
		alarm[i].m=myread(i*2+1); 
	}  
	  alarm_en=myread(i*2);        
	  alarm_wk=myread(i*2+1);
	  IE=0;  
	  IP=0;             	//disable all interrupt and lower priority
	  TMOD=0x12;            //timer 0 is set to mode 2,auto_reloading,timer1,mode 1
	  TH0=0x8d;    
	  TL0=0x8d;        		//timer0 parameters for 0.125ms
	  TH1=0x94; 
	  TL1=0x00;      		//timer1 parameters for 30ms
	  TR0=1;    
	  TR1=1;        		//timer0 interrupt most important
	  ET0=1;    
	  ET1=1;    
	  EA=1;     			//enable interrupt function
  while(1)
  { 
///////////////////////////////////
  	if(led_on)
      for(i=0;i<8;i++)
	   { 
	   P2=0xff; 
	   if( flash || attr&(0x80>>i) )  
		   { 
		   P0=display[i];  
		   P2=0xff-(0x80>>i); 
		   DelayX1ms(1); 
		   }
		}
    else  P2=0xff;  
///////////////////////////////////
    if(new_alarm_info)
     { 
		 P2=0xff;               //暂时关闭数码管   
		 new_alarm_info=0;      //写入EEPROM       
		 for(i=0;i<8;i++)  
		 { 
		   mywrite(i*2,alarm[i].h);  
		   mywrite(i*2+1,alarm[i].m); 
		 }  
		   mywrite(i*2,alarm_en);   
		   mywrite(i*2+1,alarm_wk);
	 }

  }   
}
///////////////////////////////////////////////
//程序结束
///////////////////////////////////////////////

⌨️ 快捷键说明

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