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

📄 main.c

📁 基于89S52的电子时钟
💻 C
字号:
/*--------------------------------------
单片机课程大作业:电子钟
作者:kyflash
QQ:249656058
使用AT89S52(12M)+RT1602
两个独立按键,一个蜂鸣器和一个彩色LED
按键短按实现加一减一,1S以上长按实现功能调整,2S以上长按实现快速加减
可以根据需要使用一个按键或者两个按键
另外为了判断单片机资源利用情况,从而间接验证时钟是否会因为冲突而变缓,
加上了CPU利用率显示,限于个人水平,该数据只有参考意义

由于晶振误差等因素,如果发现一周内时钟偏差较大,可以自行调整,理想的做法是
 在1s定时器中断里面加入若干个空操作语句(限于时钟快的情况)
各个功能块按顺序如下:
   调整年
   调整月
   调整日
   调整时
   调整分
   调整秒
   调整星期
   闹钟1时
   闹钟1分
   闹钟1是否开
   闹钟2时
   闹钟2分
   闹钟2是否开

关于使用到的引脚,参见各个引脚定义

说明:
    本程序仅为了应付单片机课程作业,必然存在一些不合理之处。
	程序中的按键扫描放在了定时器中断中,其实放到主循环中更好。
	程序中按键部分源自我以前参考computer00师兄在ADUC7027例成中的代码,
	做了一点小修改
	液晶驱动部分参考了网上一个程序
    
--------------------------------------*/
#include "main.h"
#include "1602.H"
#include "KEYS.h"
#include "timer.h"

volatile unsigned char menu_status=0,key_time=0;
volatile unsigned char ring_time=0;
volatile unsigned char alarm_hour1=10,alarm_minute1=2,alarm_hour2=10,alarm_minute2=4,alarm_1_ok=0,alarm_2_ok=0,
              alarm_1_en=1,alarm_2_en=1,alarm_2_off=0,alarm_1_off=0;
void delayXms(unsigned int x)   //延迟x毫秒函数
{
 unsigned int i,j;
 for(i=0;i<x;i++)
  for(j=0;j<130;j++);
}

void short_bell(void)
{
bell_on;
delayXms(50);
bell_off;
}

void long_bell(void)
{
bell_on;
delayXms(30);
bell_off;
delayXms(80);
bell_on;
delayXms(35);
bell_off;
}

void system_initial(void)   //系统初始化
{
 TMOD=0x11;                 //定时器工作在模式1
 ET0=1;                     //开定时器0中断
 TR0=1;                     //启动定时器0
 ET1=1;                     //开定时器1中断
 TL1=0x10;
 TH1=0x20;
 TR1=1;                     //启动定时器1
 EA=1;                      //开总中断
 year=2006;
 month=6;
 day=9;                    //日期初始化为2005年6月9日
 hour=10;
 minute=0;
 long_bell();
}

void display_alarm_time(unsigned char ID)
{
switch(ID)
{
case 1:
WriteCommandLCM(0x80,0);
LCD_prints("alarm1:");
WriteCommandLCM(0xc2,0);
LCD_printc(alarm_hour1/10%10+48);
LCD_printc(alarm_hour1%10+48);

LCD_printc(':');

LCD_printc(alarm_minute1/10%10+48);
LCD_printc(alarm_minute1%10+48);
if(alarm_1_en)
	 {
     WriteCommandLCM(0xc0,1);
     LCD_printc('e'); 
     }
else {
     WriteCommandLCM(0xc0,1);
     LCD_printc(' '); 
     }
break;


case 2:
WriteCommandLCM(0x80,0);
LCD_prints("alarm2:");
WriteCommandLCM(0xc2,0);
LCD_printc(alarm_hour2/10%10+48);
LCD_printc(alarm_hour2%10+48);

LCD_printc(':');

LCD_printc(alarm_minute2/10%10+48);
LCD_printc(alarm_minute2%10+48);
if(alarm_2_en)
	 {
     WriteCommandLCM(0xc0,1);
     LCD_printc('e'); 
     }
else 
     {
     WriteCommandLCM(0xc0,1);
     LCD_printc(' '); 
     }
break;
default:break;
}
}
void set_fuction(void)
{
//WriteCommandLCM(0x01,1); //显示清屏 
WriteCommandLCM(0xcb,1);
switch(menu_status)
{
case 0:
      LCD_prints("     "); //WriteCommandLCM(0x01,1); //显示清屏 
	   break;
case 1:
     LCD_prints("Year ");
	 break;
case 2:
     LCD_prints("Month");
      break;
case 3:
     LCD_prints("Date ");
	 	 break;
case 4:
     LCD_prints("Hour ");
		 break;
case 5:
     LCD_prints("Minut");
		 break;
case 6:
     LCD_prints("Secon");
	  break;
case 7:     
     LCD_prints("week "); 
    display_time();
	 break; 
case 8:  
     WriteCommandLCM(0x01,1); //显示清屏  
    // WriteCommandLCM(0x8c,0);
	WriteCommandLCM(0xcb,1);
     LCD_prints("hour");     
     display_alarm_time(1);
 	 break; 
case 9:  
     //WriteCommandLCM(0x01,1); //显示清屏 
    // WriteCommandLCM(0x8c,0);
     LCD_prints("minu");    
     display_alarm_time(1);
 	 break; 
case 10:
     LCD_prints("alarm");
     display_alarm_time(1);
	 break;
case 11:
     
    // WriteCommandLCM(0x8c,0);
     LCD_prints("hour");
   
     display_alarm_time(2);
 	 break; 
 case 12:   
    // WriteCommandLCM(0x8c,0);
     LCD_prints("minu");
     display_alarm_time(2);
 	 break; 
case 13:
      WriteCommandLCM(0x01,1); //显示清屏 
       LCD_prints("alarm");
      display_alarm_time(2);
	 break;
default:  break;
}
}
 
void key_ctrl(void)
{
if(Key.Value)	  //如果有按键按下
    {
	short_bell();
    key_time=0;  
alarm_1_off=1;
alarm_2_off=1;
led_off;//关LED闪烁
    switch(Key.Value)
	    {	
	   //  fuction
	    case KEY1L:	       
	      		 menu_status++;
				 if(menu_status>13)
				 {
				 menu_status=0;			
				 }
				 set_fuction();
				 break;
		case KEY1: 
		//"+"
		        switch(menu_status)
			   {  
		          case 0:
				        WriteCommandLCM(0xcb,0);
				        LCD_prints("LOCK!");
						break;
				  case 1: 			
				      	year++;	
						display_time();
						break;					   
				  case 2:	
				        month++;
						if(month>12)
						month=1;	
						display_time();
						break;	
				 case 3:  				        
				      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(((year%4)==0)&&((year%100)!=0))
	                         {
	                         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;
					}						      
						display_time();
						break;	
				case 4:			
				        hour++;	
						if(hour>23)
						hour=0;
						display_time();
						break;	
				case 5:		
				    	minute++;
						if(minute>59)
						minute=0;	
						display_time();
						break;	
				case 6:		
				    	second++;
						if(second>59)
						second=0;	
						display_time();
						break;		
				case 7:
				       week++;
					   if(week>7)
					   week=1;
					   display_time();
					   break;
				case 8:
				      alarm_hour1++;
					  if(alarm_hour1>23)
					  alarm_hour1=0;
					  display_alarm_time(1);
					  break;
               case 9:
				      alarm_minute1++;
					  if(alarm_minute1>59)
					  alarm_minute1=0;
					   display_alarm_time(1);
					  break;
				case 10:
				      alarm_1_en=1;
					  display_alarm_time(1);
					  break;
				case 11:
				      alarm_hour2++;
					  if(alarm_hour2>23)
					  alarm_hour2=0;
					   display_alarm_time(2);
					  break;
			    case 12:
				      alarm_minute2++;
					  if(alarm_minute2>59)
					  alarm_minute2=0;
					   display_alarm_time(2);
					  break;
				 case 13:
				      alarm_2_en=1;
					  display_alarm_time(2);
					  break;
				default:break;
				}
				break;
	     case KEY2L:		         	        
				 if(menu_status<1)
				 {
				 menu_status=13;				
				 }
				 else 	
				 menu_status--;
				 set_fuction();
				 break;
		case KEY2:   
 	    //"-"
		    switch(menu_status)
			   {
			    case 0:
				       WriteCommandLCM(0xcb,0);
     		           LCD_prints("LOCK!");
					   break;
			    case 1: 	
				      	year--;	
						display_time();
						break;					   
				 case 2:
				        if(month<2)
						month=12;
						else	
				        month--; 							
						display_time();
						break;	
				case 3: 
 				        switch(month)
						{
						case 1:
						case 3:
						case 5:
						case 7:
						case 8:
						case 10:
						case 12:			   
				             if(day<2)
						      day=31; 
                              else 
                              day--;
							  break;
						case 2:
						     if(((year%4)==0)&&((year%100)!=0))
	                         {
	                         if(day<2)                            
                                day=29;
                             else 
                                day--;
    						 }
						     else  
                             {
                             if(day<2)                             
                             day=28; 
                             else day--;
							 }
							 break;
					case 4:
                    case 6:
                    case 9:
                    case 11:
					       if(day<2)
						   day=30;
                           else 
                           day--;
						   break;
					default:break;
					}					      
						display_time();
						break;	
				case 4:	
				        if(hour<1)
						hour=23;	
						else 
						 hour--;	
						display_time();
						break;	
				case 5:		   				    			
						if(minute<1)
						minute=59;
						else 
					    minute--;	
						display_time();
						break;	
				case 6:				    	
						if(second<1)
						second=59;
						else 
						second--;	
						display_time();
						break;
				case 7:					       
					   if(week<2)
					   week=7;
					   else 
					   week--;
					   display_time();
					   break;
			    case 8: 				     
					  if(alarm_hour1<1)                     
					  alarm_hour1=23;
                      else 
                      alarm_hour1--;
					  display_alarm_time(1);
					  break;
               case 9:
				      
					  if(alarm_minute1<1)
					  alarm_minute1=59;
                      else alarm_minute1--;
					  display_alarm_time(1);
					  break;
			   case 10:
			          alarm_1_en=0;
                      display_alarm_time(1);
					 break;
				case 11:				      
					  if(alarm_hour2<1)
					  alarm_hour2=23;
                      else 
                      alarm_hour2--;
					  display_alarm_time(2);
					  break;
			    case 12:				      
					  if(alarm_minute2<1)
					  alarm_minute2=59;
                      else 
                      alarm_minute2--;
					  display_alarm_time(2);
					  break;
				 case 13:
				      alarm_2_en=0;
					  display_alarm_time(2);
					  break;
					  
				default:break;
				}		   
		     default:  break;
	          }
	         Key.Value=0;
	       } 
 	}

void main(void)            //主函数
{ 
  LCMInit();
  KEYBoardInit();
 system_initial();         //系统开机初始化
 while(1)
  {    
  key_ctrl();    //键盘扫描  
  if(key_time>=20)//如果20秒内无任何按键按下,则自动返回
  {  
  WriteCommandLCM(0xcb,0);
  LCD_prints("     ");//清除相关显示
  menu_status=0;
  key_time=0;
  }  
  //刷新显示时间
   if(time_1s_ok==1)
   {
   time_1s_ok=0;
   key_time++;   
   if(menu_status<7)
   display_time(); 
   if((alarm_1_ok==1)||(alarm_2_ok==1))//如果触发了闹钟,则对闹铃持续时间进行秒计时
   ring_time++;
   //检测闹铃时间
   if((alarm_1_en)&&(alarm_1_ok==0))
   {  
   if(alarm_hour1==hour)
     {     
     if(alarm_minute1==minute)
      {
	  if(second==0)//为了在闹铃被按键取消以后,用户能立即设置,所以强制在秒为0时才匹配/进行检测
	  {
      alarm_1_ok=1;//置闹铃1标志
      alarm_1_off=0;	  
	  ring_time=0;//清闹铃时间,同时两个闹钟的闹铃时间不叠加
      }
	  }
	 }
	}  
   if((alarm_2_en)&&(alarm_2_ok==0))//如果开了闹钟且闹钟当前没有正在闹铃,则进行检测
   {  
   if(alarm_hour2==hour)
    {
    if(alarm_minute2==minute)
     {
	 if(second==0)
	 {
     alarm_2_ok=1; //置闹铃2标志
     alarm_2_off=0;     
	 ring_time=0;
	 }
	 }
	}
   }
 
  //执行闹铃声音提示
  if(alarm_1_ok==1)
  {
  if(alarm_1_off==0)//如果用户没有按下停止键
    {
     if(ring_time<120)
              {
                WriteCommandLCM(0xc0,0);
                LCD_printc('1');
                 long_bell();
                 led_on;
               }
       else 
               {
               ring_time=0;
               led_off;
		       alarm_1_ok=0;
               }    
      
    }  
    else 
             {
               ring_time=0;
               led_off;
		       alarm_1_ok=0;
             }  
  }
   
 if(alarm_2_ok==1)
   {   
   if(alarm_2_off==0)
   {   
   if(++ring_time<120)
      {
      WriteCommandLCM(0xc0,0);
      LCD_printc('2');
      long_bell();
      led_on;
      }
   else 
     {
     ring_time=0;
     led_off;
     alarm_2_ok=0;
     }  
   }
   else 
       {
       ring_time=0;
     led_off;
     alarm_2_ok=0; 
       }

  }
  }

 }
}

 


⌨️ 快捷键说明

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