基于51单片机的电子时钟万年历温度仿真数码管显示

硬件设计

仿真图1:
A. 由数码管作为显示器,三个按键可以设置时间。
基于51单片机的电子时钟万年历温度仿真数码管显示_第1张图片
仿真图2:
A 由数码管作为显示器,可通过开关设置年月日星期等时间;
基于51单片机的电子时钟万年历温度仿真数码管显示_第2张图片

程序设计1

#include  
#define uchar unsigned char
uchar code tab[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳极数码管显示"0~9","灭"和"-"的字段码
//uchar code tab[]={0x3f,0x06,05b,0x4f,0x66,0x6d,07d,0x07,0x7f,0x6f,0x00,0x40};//共阴数码管
uchar code wetab[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};  //位选
uchar data dis[8]={0x00,0x00,0x0b,0x00,0x00,0x0b,0x00,0x00};
//显示数据缓冲区,时十、个位、分十、个位、秒十、个位初始为0,0x0b为"-"编码
uchar data timedat[3]={0x00,0x00,0x00};  //分别为秒、分和小时的计数值(记录K1和K2次数)
uchar data  ms50=0x00, num=0x00,  n1=0x00,  n2=0x00; 
//定义定时次数变量,调整模式变量,按加1键次数变量,按减1键次数变量
sbit  key0=P1^0 ;  //调整键--模式
sbit  key1=P1^1 ;  //加1键
sbit  key2=P1^2 ;  //减1键
//---------------------------------------
void  delay1ms( unsigned  int  z )  //定义延时1ms函数
{ unsigned  int  x, y ;
for  ( x=z;  x>0;  x-- )
		for  ( y=120; y>0 ;  y-- )	;
}
//---------------------------------------
//按键处理函数。如果没有按键则时钟正常走时。当按K0键1次→暂停走时进入调小时状态;再按K0键1次→进入调分钟状态;再按K0键1次→回到正常走时状态。对于K1和K2键,如果正常走时下→按K1K2键不起作用;如果进入调时或者调分状态→按K1键可对时或分加1操作,小时加到24则回0,分钟加到60则回0。按K2键可对时或分减1操作,小时减到负则回23,分钟减到负则回59。
 void keyscan(  void )
{	EA=0;  //关中断
	if(timedat[0]==0&timedat[1]==0&timedat[2]==7)  {P1=0xff;}
if (key0==0)	 { delay1ms(10); 	while (key0==0);
			num++; TR0=0; ET0=0;  // 调整键K0每按1次--模式变量num加1
			if (num>=3) 	{num=0;  ET0=1;  TR0=1;  }  // 启动T0校时
	}
		if (num!=0)	//模式变量不等于0
{	if (key1==0)        // K1键确实按下
	 {	delay1ms(10); 	while (key1==0);   	timedat[num]++;  //记录按键K1按下次数
				if (num==2) n1=24;  else n1=60;		//模式变量等于小时2--则回迟到一天或60分钟
if (timedat[num]>=n1)  	{ timedat[num]=0; }  	}
		}
		if (num!=0)
		 {	if (key2==0)	
{	delay1ms(10);	while (key2==0); 		timedat[num]--;  //记录按键K2按下次数
				if (num==2) n2=23;else n2=59;			
				if (timedat[num]<=0)  		{timedat[num]=n2; }  	}
		}
		 EA=1;
	}
//---------------------------------------
//数码管显示函数。时间显示先秒个位计算显示→秒十位计算显示→再分个位计算显示→分十位显示→再时个位计算显示→时十位显示。
	 void  display( void )
	{ 	 uchar k;
		if(timedat[0]==0&timedat[1]==0&timedat[2]==7)  {P1=0xff;}
		 dis[0]=timedat[0]%10;  dis[1]=timedat[0]/10;   //秒
 dis[3]=timedat[1]%10;  dis[4]=timedat[1]/10;  //分
dis[6]=timedat[2]%10;  dis[7]=timedat[2]/10;  //时
for ( k=0;  k<8;  k++ )
			{ 	P0=tab[ dis[k] ];  P2=wetab[k];    delay1ms(1);     P2=0x00; 	}
	}	
//---------------------------------------
//主函数,时间显示先秒个位计算显示,然后是秒十位计算显示;再就是分个位计算显示,然后是分十位显示;再就是时个位计算显示,然后是时十位显示。定时器中断先检测1秒是否到→1秒如果到则秒单元加1;1秒如果没到就检测1分钟是否到→1分钟如果到则分单元加1;如果没到就检测1小时是否到→1小时如果到则时单元加1;如果没到→则显示时间。
	 void main( void )
	{   TMOD=0x01;   //T0定时50ms,方式1
		EA=1;  ET0=1;  TR0=1;  //开中断,允许T0中断,启动T0
		TH0=0x3c;  TL0=0xb0;
		while (1)
			{ 	display( ) ;
				keyscan( ) ;
			}
}
//定时器/计数器T0中断服务函数。定时器中断先检测1秒是否到→1秒如果到则秒单元加1;1秒如果没到就检测1分钟是否到→1分钟如果到则分单元加1;如果没到就检测1小时是否到→1小时如果到则时单元加1;如果没到→则显示时间。
  void  timer0(void)  interrupt  1
{ ET0=0; TR0=0;   //不许T0中断也不启动
TH0=0x3c;  TL0=0xb0;  
TR0=1;  //启动T0
ms50++;
P1=0xf7;
	 if(timedat[0]==0&timedat[1]==0&timedat[2]==7)  {P1=0xff;}
if (ms50==20) 	{	ms50=0x00;  timedat[0]++;  //变量m回0,且秒加1
		if (timedat[0]==60)  	{ 	timedat[0]=0;timedat[1]++;  //秒到60后回0,且分加1
			if (timedat[1]==60) 	{ 	timedat[1]=0;timedat[2]++;  //分到60后回0,且时加1
				if (timedat[2]==24) 	{ 	timedat[2]=0; 	} 	}	}  //时到24后回0
				 
	}
	ET0=1;   //允许T0中断
}

程序设计2

#include
#include
#define uchar unsigned char 
#define uint  unsigned int
#define ture  1
#define fault 0

sbit SET=P1^7;

void  delay(uchar  k) ;
uchar monthday(uchar a,uchar b);
void display()	;

uchar code dayofmonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
uchar code scan[]={0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,
                    0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
					0xf8,0xf9,0xfa,0xfb,0xfc,0xfd};
					//扫描的译码信号
uchar i;
uchar code table[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0xA7,0xFF,0xEF,0xC0};
uchar  buffer[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uchar  shuju=0;
uchar  state=0;
uchar  qxiang;

typedef  struct  
         {
		 uchar year[2];
		 uchar month;
		 uchar day;
		 uchar week;
		 }date;
typedef  struct  
        {
	    uchar hour;
		uchar minute;
		uchar second;
		}time;
uchar  count=0;
date today={{9,20},4,20,1};
time now={11,8,10};
void main()
{
TMOD=0x01;
TL0=(65536-1000)%256;
TH0=(65536-1000)/256;
IE=0x82;	  //EA=1;ET0=1总中断允许和定时器中断允许
TCON=0x10;	  //定时器启动计数
while(1)
    {
	 P1=0xff;

	 shuju=P1&0xff;
	 qxiang=shuju&0x80;
		switch(qxiang)
	    {
		 case(0x80):switch(shuju)
			      {
				 case(0xfe) :			   //秒调整
		            {
					 EA=1;
					 EX0=1;           //IE=0x83;			//EA=1;ET0=1;EX0=0总中断允许,定时器中断允许,外中断允许
					 IT0=1;           //TCON=0x11;			//TR0=1;IT0=1;定时器启动,外中断为负边沿触发
			         }break;
	           	 case(0xfd)	:			 //分调整
		            {
					 EA=1;
					 EX0=1;                  // IE=0x83;
					 IT0=1;                    //TCON=0x11;
			         }break;
	           	 case(0xfb) :			//时调整
		            {
					EA=1;
					 EX0=1;
					 IT0=1;
					
			         }break;
                 case(0xf7) :			   //星期调整
		            {
					EA=1;
					 EX0=1;
					 IT0=1;
			      
			         }break;
                 case(0xef) :					//日调整
	 	            {
					EA=1;
					 EX0=1;
					 IT0=1;
				
			         }break;
                 case(0xdf):				 //月调整
	 	            {
					EA=1;
					 EX0=1;
					 IT0=1;
				
			         }break;
                 case(0xbf):					//年调整
		            {
					EA=1;
					 EX0=1;
					 IT0=1;
					
			         }break;
			     default:						 //时钟正常计时
	                {
					EA=1;
					TR0=1;
					EX0=0;
				
					}break;
				}break;
		 case(0x00) :switch(shuju)
					     {
			   case(0x7e):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
					
					}break;
	           case(0x7d):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
				
					}break;
	           case(0x7b):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
			    
					}break;
	           case(0x77):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
				
					}break;
	           case(0x6f):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
					
					}break;
	           case(0x5f):
	                {
					 EA=1;
					 EX0=1;
					 IT0=1;
					
					}break;
	           case(0x3f):
	                {
					EA=1;
					 EX0=1;
					 IT0=1;
					
					}break;
	           default:						 //时钟正常计时
	                {
					EA=1;
					TR0=1;
					EX0=0;
						
					}break;
		    	}break;       
		}
	}
}

void inter0()  interrupt 0  using 0
  {
  uchar result,z; 
  result=shuju;
       	switch(qxiang)
	    {
		 case(0x80):   switch(result)
					   {
                       	case(0xfe) :					  // if(result==0xfe)				   //秒调整	+
	                         {
	                           now.second++;
	                           if(now.second>=60)
	                              {
		                            now.second=0;
		                           }
	                           display();
	                          }break;
   
                         case(0xfd) :		             //if(result==0xfd)					 //分调整  +
	                         {
	                            now.minute++;
	                            if(now.minute>=60)
	                             {
		                           now.minute=0;
		                          }
	                             display();
	                         }break;
   
                            case(0xfb) :		   //if(result==0xfb)				   //时调整	+
	                          {
	                             now.hour++;
	                             if(now.hour>=24)
	                                {
		                              now.hour=0;
	                             	}
	                                display();
	                          }break;
 
                             case(0xf7)	:		  // if(result==0xf7)	               //星期调整 +
	                              {		   
	                                 today.week++;
	                                  if(today.week>=8)
	                                      {
		                                    today.week=1;
		                                   }
	                                  display();
	                              }break;

	                          case(0xef) :			//if(result==0xef)				   //日期调整	 +
	                              {
	                                 today.day++;
	                                 z = monthday( today.year[1]  ,  today.year[0] );
	                                 if((z==1)&&(today.month==2))
									    {
										  if(today.day>=30)
			                                 today.day=1;
										}

		                              else if (today.day>dayofmonth[today.month-1])
		                                            today.day=1;
	                                   display();
	                                }break;	  
   	
	                          case(0xdf) :			 //if(result==0xdf)					//月调整	+
		
		                            {
	                                	today.month++;
	           	                        if(today.month>=13)
		                                   {
			                                 today.month=1;
			                                }
		                                display();
		                               } break;
   
	    
		                       case(0xbf) :					 //if(result==0xbf)					  //年调整 +
		                             {
	                                   today.year[0]=today.year[0]+1;
		                               if(today.year[0]>=100)
		                                   {
			                                 today.year[0]=0;
			                                 today.year[1]=today.year[1]+1;
			                                 if(today.year[1]>=100)
			                                    {
				                                   today.year[1]=0;
				                                 }
			                                 }
		                                 display();
	 	                              }break;
		                       default:						 //时钟正常计时
	                                 {
									 EA=1;
					                 TR0=1;
					                 EX0=0;
									 		                 
					                 }break;
					         }break; 
					
  case(0x00): switch(result)
			{
			  case(0x7e):				//if(result==0x7f)					 //秒调整—
	                  {
	   	               if(now.second>0)
		                  now.second=now.second-1;
		               else  now.second=59;
		                    display();
	                  }break;
	
  case(0x7d):						//if(result==0x7d)					  //分调整—
	   {
	   	if(now.minute>0)
		   now.minute=now.minute-1;
		else now.minute=59;
		display();
	   }  break;
	
  case(0x7b) :					  //if(result==0x7b)					  //  时调整-
	   
	   {
	   	if(now.hour>0)
		   now.hour=now.hour-1;
		else now.hour=23 ;
		display();
	   }break;
	
	case(0x77) :					 //if(result==0x77)					 //	 周调整—
	   {
	    if(today.week>1)
		   today.week=today.week-1;
		else today.week=7;
		display();
	   }break;

附:http://www.jh-tec.cn/archives/7127

你可能感兴趣的:(51单片机,单片机,fpga开发)