天天看點

時鐘及規定時間鬧鐘題目要求:用按鍵設定時鐘的時、分、秒。要求用4鍵方式,即選擇、加、減、确認鍵,選擇鍵用于選擇修改起始時、分、秒值,每按一次,被修改數位管順序移動并閃爍。用+,- 鍵修改數值,确認鍵确定修改結束。用掃描方式動态顯示時、分、秒,第2,4 數位管加小數點,并且要求第4數位管小數點每秒閃爍一次。可以設定鬧鐘,到時間蜂鳴器報警代碼講解:

時鐘及規定時間鬧鐘

題目要求:用按鍵設定時鐘的時、分、秒。要求用4鍵方式,即選擇、加、減、确認鍵,選擇鍵用于選擇修改起始時、分、秒值,每按一次,被修改數位管順序移動并閃爍。用+,- 鍵修改數值,确認鍵确定修改結束。用掃描方式動态顯示時、分、秒,第2,4 數位管加小數點,并且要求第4數位管小數點每秒閃爍一次。可以設定鬧鐘,到時間蜂鳴器報警

難點及技巧:

1、通過在定時器中斷來設定标志位來控制數位管的閃爍

2、八位數位管小數點的點亮,0x80,通過或與句(|0x80)

3、數位管的閃爍,通過if語句,對标志位進行求餘(閃爍,對2求餘即可)

話不多說,直接看代碼

代碼講解:

源代碼:

#include "reg52.h"			 //此檔案中定義了單片機的一些特殊功能寄存器
#include<intrins.h> 

typedef unsigned int u16;	  //對資料類型進行聲明定義
typedef unsigned char u8;

sbit LSA=P2^2;			  //38譯碼器
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit buzz=P2^5;	 //蜂鳴器

sbit k1=P3^1;  //選擇鍵
sbit k2=P3^0;  //加一				
sbit k3=P3^2;  //減一 
sbit k4=P3^3;  //确認健

//數位表
u8 code lzl[17]={    0x3f,0x06,0x5b,
	                 0x4f,0x66,0x6d,
	                 0x7d,0x07,0x7f,
                     0x6f,0x77,0x7c,
                     0x39,0x5e,0x79, 
                     0x71};

u8 ssec,sec,min,hour; //毫秒,秒,分,時
u8 model,sign;    //标志位
u8 wei[8];

u8 uhour=0,umin=0,usec=5;	   //鬧鐘時間設定

void delay(u16 i);	  //延時函數
void Timer0Init();	  //中斷函數初始化
void display();	      //動态顯示
void show();	      //顯示數位管
void key_scan();      //按鍵功能    k1:選擇健   k2:加一   k3:減一   k4:确認健
void start();         //函數總和

										 
void delay(u16 i)	 //延時函數
{
	while(i--);	
}


void Timer0Init()
{
	TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。
	TH0=0Xd8;	//給定時器賦初值,定時10ms
	TL0=0Xf0;	
	ET0=1;//打開定時器0中斷允許               //注:稍後用K2控制總中斷,實作暫停功能
	EA=1;//打開總中斷	
	TR0=1;//打開定時器				 防止未按就計時
}




//動态顯示函數
void display()
   {
   u8 i;
   for(i=0;i<8;i++)
   {
   	switch(i)	 //位選,選擇點亮的數位管,
   	{
   		case(0):
   			LSA=1;LSB=1;LSC=1; break;
   		case(1):
   			LSA=0;LSB=1;LSC=1; break;
   		case(2):
   			LSA=1;LSB=0;LSC=1; break;
   		case(3):
   			LSA=0;LSB=0;LSC=1; break;
   		case(4):
   			LSA=1;LSB=1;LSC=0; break; 
   		case(5):
   			LSA=0;LSB=1;LSC=0; break;
   		case(6):
   			LSA=1;LSB=0;LSC=0; break;
   		case(7):
   			LSA=0;LSB=0;LSC=0; break;	
   	}
   	P0=wei[i];			//發送段碼
   	delay(100); 		//間隔一段時間掃描	
   	P0=0x00;
   }
 }


//記錄數位管顯示

void show()		
   {
	 wei[2]=0;
	 wei[5]=0;
   switch(model)
   {
   	case 0:
   	{
   		wei[0]=lzl[hour/10];		
   		if(sign%2==0)						
   			wei[1]=lzl[hour%10]|0x80;
   		else
   			wei[1]=lzl[hour%10];

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		break;
   	}
   	case 1:
   	{
   		if(sign%2==0)
   		{								
   			wei[0]=lzl[hour/10];		
   			if(sign%2==0)
   				wei[1]=lzl[hour%10]|0x80;
   			else
   				wei[1]=lzl[hour%10];

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=0x00;
   			wei[7]=0x00;
   		}
   		else
   		{							 
   			wei[0]=lzl[hour/10];		
   			if(sign%2==0)
   				wei[1]=lzl[hour%10]|0x80;
   			else
   				wei[1]=lzl[hour%10];

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		}
   		break;
   	}
   	case 2:					  
   	{
   		if(sign%2==0)
   		{
   			wei[0]=lzl[hour/10];						
   			if(sign%2==0)
   				wei[1]=lzl[hour%10]|0x80;
   			else
   				wei[1]=lzl[hour%10];

   			wei[3]=0x00;
   			wei[4]=0x00|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		}
   		else
   		{
   			wei[0]=lzl[hour/10];		
   			if(sign%2==0)
   				wei[1]=lzl[hour%10]|0x80;
   			else
   				wei[1]=lzl[hour%10];

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		}
   	}
   		break;
   	case 3:
   	{
   		if(sign%2==0)										   
   		{
   			wei[0]=0x00;		
   			if(sign%2==0)
   				wei[1]=0x00|0x80;
   			else
   				wei[1]=0x00;

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		}
   		else
   		{
   			wei[0]=lzl[hour/10];		
   			if(sign%2==0)
   				wei[1]=lzl[hour%10]|0x80;
   			else
   				wei[1]=lzl[hour%10];

   			wei[3]=lzl[min/10];
   			wei[4]=lzl[min%10]|0x80;
   			wei[6]=lzl[sec/10];
   			wei[7]=lzl[sec%10];
   		}
   		break;
   	}
   }
   }

//按鍵掃描及處理

  void key_scan()
  {
  if(k1==0)
  {
  	delay(1000);
  	if(k1==0)
  	{
  	model++;
  	while(!k1);
  	if(model==4)
  		model=0;
  	}
  }

  if(k2==0)
  {
  	delay(1000);
  	if(k2==0)
  	{
  		if(model==1)		//修改秒
  		{
  			sec++;	if(sec>=60)sec=0;
  		}
  		else if(model==2)	//修改分鐘
  		{
  			min++;	if(min>=60)min=0;
  		}
  		else if(model==3)	//修改小時
  		{
  			hour++;	if(hour>=24)hour=0;
  		}
  		while(!k2);
  	}
  }

  if(k3==0)
  {
  	delay(1000);
  	if(k3==0)
  	{
  		if(model==1)		//修改秒
  		{
  			sec--;	if(sec==255)sec=59;
  		}
  		else if(model==2)	//修改分鐘
  		{
  			min--;	if(min==255)min=59;
  		}
  		else if(model==3)	//修改小時
  		{
  			hour--;	if(hour==255)hour=23;
  		}
  		while(!k3);
  	}
  }
  if(k4==0)				  //恢複初态
  {
  	delay(1000);
  	if(k4==0)
  		model=0;
  	while(!k4);
  }

  if(min==umin)				//鬧鐘,自己定義時間
  {
  	if(hour==uhour)
	{
		if(sec==usec)
		{
		   buzz=~buzz;
    	}
	}
  }

}

void start()
{
      display();
      show();
	  key_scan();	
}


//主函數
void main()
{
	Timer0Init(); //設定外部中斷	
	while(1)
	{
  	start();
     }

}



void Timer0() interrupt 1
{
	TH0=0Xd8;	//給定時器賦初值,定時10ms
	TL0=0Xf0;
	ssec++;
					
	 if(ssec>=100)  //1s
	{
		ssec=0;
		sec++;
		sign++;
		if(sec>=60)
		{

			sec=0;
			min++;
			if(min>=60)
			{	  
				min=0;
				hour++;
				if(hour>=24)
				{
					hour=0;
				}
			}
		}	
	}
			
}

	
           

繼續閱讀