设计思路:

每次key1按键按下,秒表在启动/暂停之间切换;

每次key2按键按下,秒表清零并暂停;

秒表显示目前记录的秒数,启动时,每秒加1,暂停时显示无变化;


达到60秒后,LED提示灯闪烁三次,之后自动切换为00,并重新计时。

仿真元器件清单:

7SEG-COM-CATHODE

AT89C51

BUTTON

CAP

CRYSTAL

RES

RESPACK-7

LED

实现程序:

#include<reg51.h>
unsigned char duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit key1=P1^0;
sbit key2=P1^1;
sbit led=P3^0;
bit run;
unsigned char count,j;
unsigned char count,i;
void delay(unsigned int z)
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=125;y>0;y--);

}
void main()
{
	P0=0;
	P2=0;
	key1=1;
	key2=1;
	TMOD=0x01;
	TH0=0x3c;
	TL0=0xb0;
	EA=1;
	ET0=1;
	while(1)
	{
		if(key1==0)
		{
			run=1;
		}
		else if(key2==0)
		{
			run=0;
			count=0;
		}
		if(run)
		{	if(key1==0)
           {
			TR0=~TR0;
			while(!key1);
			}
		}
		else
		{
			TR0=0;
			P0=duan[0];
			P2=duan[0];
		}
	}

}

void time0()interrupt 1
{
	i++;
	if(i==20)
	{
		i=0;
		count++;
	    if(count>=60)
	    {
		    P0=duan[6];
			P2=duan[0];
			delay(1000);
			count=0;
			P0=duan[0];
			P2=duan[0];
			TR0=1;
                        for(j=0;j<6;j++)
                        {
                            led=~led;
                            delay(500);
                         }
	    }	
	    P0=duan[count/10];
	    P2=duan[count%10];
	}
	TH0=0x3c;
	TL0=0xb0;
}

 

实现仿真图:

实现效果视频:

 

进阶版(转载):

达到60秒后,LED提示灯闪烁三次,每次0.5*2。并不会影响计时和显示的正常节奏。

7SEG-COM-CATHODE替换为7SEG-MPX1-CA

程序为

   #include<reg51.h>
   sbit LED=P1^0;
   sbit KEY1=P3^2;  //启动/暂停按键
   sbit KEY2=P3^3;  //清零按键
   unsigned char duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
   unsigned char miao,i,half_miao;flag;

   void main()
   {
        KEY1=1;KEY2=1;TR0=0; LED=1;miao=0;half_miao=0;flag=10;//设置初始状态
   	TMOD=0x11;               
        TH0=(65536-50000)/256;	 //设置50ms定时的初始值
   	TL0=(65536-50000)%256;
        EA=1; ET0=1;EX0=1;EX1=1;//开启中断
	PX0=1;PX1=1;  			//确保外部按键中断优先于定时器
	P0=duan[miao/10];		//显示时间初始值
	P2=duan[miao%10];	
   	while(1);           //无限循环,交给中断自行处理
    }

   void int0() interrupt 0 //按键1产生外部中断0
   {
        TR0=~TR0;// 外部中断0 在启动or暂停之间切换
    }          

   void int1() interrupt 1 //定时计数器0 每50ms
  { 
        i++;                   //50ms计数值加1
   	if(i==10)              //每10次 0.5s
	  {
             i=0;              		 //计数值归0
  	     half_miao++;  		//0.5s记录值加1	
	      if(half_miao%2==0)    //0.5s记录值为偶数,即每1s
	      miao++;  
	      P0=duan[miao/10];   //显示新的时间
	      P2=duan[miao%10];				 
	      if(miao==60)           //60秒时  
	    	{
                   miao=0;            //时间清0
		   flag=0;          //将闪烁标志数从初值10改为0,准备开启闪烁
                  }	           
		 switch(flag)
			{ case 0:LED=0;break;
			  case 1:LED=1;break;
			  case 2:LED=0;break;
			  case 3:LED=1;break;
			  case 4:LED=0;break;
			  case 5:LED=1;break;
			  default:break;
			  }	
		if(flag<6) flag++;	     //在闪烁期间,每50ms将闪烁标志数增加1				
	     }
	TH0=(65536-50000)/256;	 //每次计数循环都需要重新设置50ms定时的初始值
        TL0=(65536-50000)%256;		
   }

   void int2() interrupt 2 //按键2清零
   { 
      miao=0;
      half_miao=0;   
    }

仿真图:

实现效果视频