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

📄 数字钟完成.txt

📁 基于51单片机的数字钟程序
💻 TXT
字号:
#include<reg52.h>
void time0(void);                     //中断程序0,用来计时
void time1(void);                     //中断程序1,用来动态显示
void charge_buffer_1(void);           //用来处理时钟的进位
void charge_buffer_2(void);           //用来处理秒表的进位
void charge_buffer_3(void);           //用来处理日期的进位
void init_data(void);                 //初始化一些乱七八糟的数
void init_buffer_0(void);             //初始化缓冲区0
void init_buffer_1(void);             //初始化缓冲区1
void init_buffer_2(void);             //初始化缓冲区2
void init_buffer_3(void);             //初始化缓冲区3
void which_line_key_down();           //判断是哪个键按下,赋值给line
void delay_10ms();                    //精确延时10ms
void delay_100ms();                   //延时100ms,不太精确
bit if_keydown();                     //判断第0行的键有没有按下
unsigned char line,displace_1,displace_3;
bit start_1,start_2,start_3,flag;
unsigned char timer,tim,lighting;
unsigned char buff,buffer_0[6],buffer_1[6],buffer_2[6],buffer_3[6];   
unsigned char code tab_1[14]={0x3f,0X06,0X5B,0X4F,0X66,0X6D,0X7D,
                              0x07,0x7f,0x6f,0x76,0x79,0x38,0x86}; //p2的取值
unsigned char code tab_2[7]={0X01,0X02,0X04,0x08,0X10,0X20,0x40};    //p1的取值
void main(void) 
{   
    init_buffer_0();
    init_buffer_1();
    init_buffer_2();
	init_buffer_3();
	init_data();
    
    do{
             if(if_keydown())
			 {	
				which_line_key_down();
		     }
		      if(buff==1&&start_1)             //如果当前显示模式为1(时钟模式),且修改模式开启,执行相应操作
			  {
			       if(line==2)                 //"2"键切换要修改的内容
			       {    
			          displace_1++;            //"displace_1"指向修改的位置
					  delay_100ms();
                      delay_100ms();
			       }
                   if(displace_1>2) displace_1=displace_1-3;
				   if(line==3)                 //"3"键执行修改
				   {
				      switch(displace_1)
                      {
					     //在每个操作后面都调用进位函数和延时函数
			             case 2:if(buffer_1[4]<3){buffer_1[5]=0;buffer_1[4]=0;}
						        else{buffer_1[5]=0;buffer_1[4]=0;buffer_1[3]++;charge_buffer_1();}break;
			             case 1:buffer_1[3]++;charge_buffer_1();delay_100ms();delay_100ms();break;
			             case 0:buffer_1[1]++;charge_buffer_1();delay_100ms();delay_100ms();break;
                      }
			    	}
			  
			  }
              if(start_3&&buff==3)             //如果当前显示模式为3(日期模式),且修改模式开启,执行相应操作
			  {
			       if(line==2)                 //同模式1类似
			       {    
			          displace_3++;
					  delay_100ms();
                      delay_100ms();
			       }
                   if(displace_3>2) displace_3=displace_3-3;
				   if(line==3)
				   {
				      switch(displace_3)
                      {
			             case 2:buffer_3[5]++;charge_buffer_3();delay_100ms();delay_100ms();break;
			             case 1:buffer_3[3]++;charge_buffer_3();delay_100ms();delay_100ms();break;
			             case 0:buffer_3[1]++;charge_buffer_3();delay_100ms();delay_100ms();break;
                      }
			    	}
			  
			  }
		      if(start_2)                  //如果模式2(秒表模式)的计时开启,执行操作
			  {
		         delay_10ms();             //计时开启时,该函数有计时功能
			  }
			  else if(!start_2&&line==2)   //如果计时停止且"2"键按下
			  {    
			     init_buffer_2();          //清零
			  }
              delay_10ms();                //延时
		      line=4;                      //赋初值
    }while(1);
}
void time0(void) interrupt 1 using 0
{
    if(!timer)
	{
	    buffer_1[5]=buffer_1[5]+1;        //到了1s的时候时钟末尾加1
        charge_buffer_1();                //调用进位函数
	    TH0=0Xbe;                         //赋初值
	    TL0=0X00;
		timer=15;
	}
	else{timer--;}
	TR0=1;
	
}
void time1(void) interrupt 3 using 0
{
           unsigned char a;
	       a=6-tim;
	       P1=tab_2[a];
           if(buff==0)
		   {
		       P2=tab_1[buffer_0[a]];
  		   }
		   if(buff==1)
		   {
		       if(start_1)               //模式1下进入修改模式
			   {
			      //以下部分实现被修改内容的闪烁,通过p1的取值实现
			      if(lighting&&flag) 
			      { 
			         if(a==2*displace_1||a==1+2*displace_1)
	                 { 
					    P1=tab_2[6];
				     }
			      }
                  lighting--;
                  if(!lighting)
				  {   lighting=80;
				      flag=!flag;
				  }
			   }
               P2=tab_1[buffer_1[a]];
		       
		   }
		   if(buff==2)
		   {
		       P2=tab_1[buffer_2[a]];
  		   }
           if(buff==3)
		   { 
		       //同模式1类似
               if(start_3) 
			   {
			      if(lighting&&flag)
			      {
			         if(a==2*displace_3||a==1+2*displace_3)
	                 { P1=tab_2[6];
					   
				     }
			      }
                  lighting--;
                  if(!lighting)
				  {   lighting=80;
				      flag=!flag;
				  }
			   }
               P2=tab_1[buffer_3[a]];
  		   }
		   tim--;
		   if(tim==0)
	       {
	           tim=6;	
	       }
    TR1=1;
    TH1=0Xf3;
	TL1=0Xff;
	
}

bit if_keydown()
{
    unsigned char i;
	P0=0xf0;          //将所有列的电位置为0
	i=P0;
	if(i==0x70)       //第一行有键按下时最高位必然为0
	{
		delay_10ms();
        //delay_10ms();
		i=P0;
		if(i==0x70)
			{return 1;}
		else return 0;
	}
	return 0;
}

void which_line_key_down()
{
    unsigned char d;
	P0=0x0f;
 	d=P0;
	switch(d)
	{
			case 0x07:line=3;break;
			case 0x0b:line=2;break;
			case 0x0d:line=1;if(buff==1){start_1=!start_1;}if(buff==2){start_2=!start_2;}    //启动/停止
                             if(buff==3){start_3=!start_3;}delay_100ms();delay_100ms();break;
			case 0x0e:line=0,buff++;if(buff>3){buff=buff-3;}delay_100ms();delay_100ms();break; //切换显示模式
	}
}


//时钟的进位函数
void charge_buffer_1(void)
{
    
    if(buffer_1[5]==10)
	{
	    buffer_1[5]=0;
		buffer_1[4]=buffer_1[4]+1;
	}
    if(buffer_1[4]==6)
	{
	    buffer_1[4]=0;
		//if(!start_1)        //正常计时才进位,在修改模式下不进位,以免互相影响
buffer_1[3]=buffer_1[3]+1;
	}
    if(buffer_1[3]==10)
	{
	    buffer_1[3]=0;
		buffer_1[2]=buffer_1[2]+1;
	}
    if(buffer_1[2]==6)
	{
	    buffer_1[2]=0;
	//	if(!start_1)          //同上
buffer_1[1]=buffer_1[1]+1;
	}
    if(buffer_1[1]==10&&buffer_1[0]<2)
	{
	    buffer_1[1]=0;
		buffer_1[0]=buffer_1[0]+1;
	}
    if(buffer_1[1]==4&&buffer_1[0]>=2)
	{
	    buffer_1[1]=0;
		buffer_1[0]=0;
        //if(!start_1)
buffer_3[5]=buffer_3[5]+1;
	}
}	

//秒表的进位函数
void charge_buffer_2(void)
{ 
    if(buffer_2[5]==10)
	{
	    buffer_2[5]=0;
		buffer_2[4]=buffer_2[4]+1;
	}
    if(buffer_2[4]==10)
	{
	    buffer_2[4]=0;
		buffer_2[3]=buffer_2[3]+1;
	}
    if(buffer_2[3]==10)
	{
	    buffer_2[3]=0;
		buffer_2[2]=buffer_2[2]+1;
	}
    if(buffer_2[2]==6)
	{
	    buffer_2[2]=0;
		buffer_2[1]=buffer_2[1]+1;
	}
    if(buffer_2[1]==10)
	{
	    buffer_2[1]=0;
		buffer_2[0]=buffer_2[0]+1;
	}
    if(buffer_2[0]==6)
	{
		buffer_2[0]=0;         //秒表只能记1小时以下的时间
	}

}

//日期的进位函数,由于有闰年,以及每个月的天数也不同,所以进位函数较复杂,且日期只能记到99年
void charge_buffer_3(void)
{
    unsigned char i=0,j=0,m,n;
	if(!((buffer_3[0]*10+buffer_3[1])%4)) {i=1;}   //闰年        
	if(buffer_3[2]==0)
	{
	    if(buffer_3[3]==1||buffer_3[3]==3||buffer_3[3]==5||buffer_3[3]==7||buffer_3[3]==8) 
	    {j=1;}                                    //大月
	}
	if(buffer_3[2]==1)
	{
	    if(buffer_3[3]==0||buffer_3[3]==2)
		{j=1;}
	}
	n=j+1;         //大约时n为1,否则为0                     
	m=8+i+1;       //闰年时m为30,否则为29
    if((buffer_3[2]==0)&&(buffer_3[3]==2))
	{
        if(buffer_3[5]==10&&buffer_3[4]<2)
	    {
	        buffer_3[5]=0;
		    buffer_3[4]=buffer_3[4]+1;
	    }
        if((buffer_3[4]>=2)&&(buffer_3[5]==m))
	    {		    
	        buffer_3[5]=1;
		    buffer_3[4]=0;
            //if(!start_3)
		   buffer_3[3]=buffer_3[3]+1;
		}
	}
	else 
	{
	    if(buffer_3[5]==10&&buffer_3[4]<3)
	    {
	        buffer_3[5]=0;
		    buffer_3[4]++;
	    }
        if((buffer_3[4]>=3)&&(buffer_3[5]==n))
	    {
	        buffer_3[5]=1;
		    buffer_3[4]=0;
            //if(!start_3)
		   buffer_3[3]=buffer_3[3]+1;
		}
	}
    if(buffer_3[3]==10&&buffer_3[2]<1)
	{
	     buffer_3[3]=0;
		 buffer_3[2]++;
	}
    if((buffer_3[2]>=1)&&(buffer_3[3]==3))
	{
	     buffer_3[3]=1;
		 buffer_3[2]=0;
         //if(!start_3)
		buffer_3[1]=buffer_3[1]+1;
	}
    if(buffer_3[1]==10)
	{
	     buffer_3[1]=0;
		 buffer_3[0]++;
	}
    if(buffer_3[0]==10)
	{
	     buffer_3[0]=0;
	}
}


void delay_10ms()
{
    unsigned char i,j;
	for(i=0;i<150;i++)
	for(j=0;j<20;j++)
	;
	if(start_2)
	{
	    buffer_2[5]++;
		charge_buffer_2();
	}
}

void delay_100ms()
{
    unsigned char i,j;
	for(i=0;i<119;i++)
	for(j=0;j<200;j++)
	;
}

void init_data()
{
    buff=0;
    start_1=0;
	start_2=0;
	flag=1;
	displace_1=0;
    displace_3=0;
	lighting=80;
    TMOD=0x11;
	IE=0X8a;
    TCON=0X11;
    PT0=1;
	tim=6; 
	timer=15;
	TH0=0Xbe;
	TL0=0X00;
	TR0=1;
	TR1=1;
}

void init_buffer_0()
{
    buffer_0[0]=10;
    buffer_0[1]=11;
    buffer_0[2]=12;
    buffer_0[3]=12;
    buffer_0[4]=0;
    buffer_0[5]=13;
}

void init_buffer_1()
{
    buffer_1[0]=0;
    buffer_1[1]=0;
    buffer_1[2]=0;
    buffer_1[3]=0;
    buffer_1[4]=0;
    buffer_1[5]=0;
}

void init_buffer_2()
{
    buffer_2[0]=0;
    buffer_2[1]=0;
    buffer_2[2]=0;
    buffer_2[3]=0;
    buffer_2[4]=0;
    buffer_2[5]=0;
}

void init_buffer_3()
{
    buffer_3[0]=0;
    buffer_3[1]=6;
    buffer_3[2]=0;
    buffer_3[3]=9;
    buffer_3[4]=0;
    buffer_3[5]=7;
}

⌨️ 快捷键说明

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