51单片机005:用动态扫描方法和定时器1在数码管显示出秒表,精确到1%秒,即后两位显示1%秒(xx.yy),一直循环下去,按K1停止计时,K2重新开始,K3清0停表。

题目:用动态扫描方法和定时器1在数码管显示出秒表,精确到1%秒,即后两位显示1%秒(xx.yy),一直循环下去,按K1停止计时,K2重新开始,K3清0停表。

思路:

1、“用动态扫描方法和定时器1”:

动态扫描要用到数码管的位选和段选,定时器要初始化、编写中断服务函数。

2、“后两位显示1%秒(xx.yy)”:

定义分钟和秒的变量,定时器计数变量每过1s,秒变量++,当秒变量达到60时,分钟变量++。

3、“按K1停止计时,K2重新开始,K3清0停表”

独立按键,通过看按键是否为低电平,判断按键是否按下。通过延时进行消抖。由于要经常检查按键情况,所以应该写到死循环里。

通过控制TCON寄存器中的TR1/TR0运行控制寄存器,控制定时器运行,进一步控制秒表停止计时和重新开始计时。将分钟变量和时钟变量清零即可将秒表清零。

涉及原理图:

代码:

#include "reg52.h"

//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

//定义独立按键控制脚
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;

unsigned int h,min,sec; //时变量,分钟变量,秒变量

//共阴极数码管显示0~F的段码数据
unsigned char gsmg_code[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
				0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};

//延时函数
void delay_10us(unsigned int ten_us)
{
	while(ten_us--);	
}

/*****************************数码管*****************************/
void shumaguan(unsigned char location,number)
{
	P0=0x00;
  switch(location)
	{ 
	  case 8:LSC=0;LSB=0;LSA=0;break;
		case 7:LSC=0;LSB=0;LSA=1;break;
	  case 6:LSC=0;LSB=1;LSA=0;break;
	  case 5:LSC=0;LSB=1;LSA=1;break;
		case 4:LSC=1;LSB=0;LSA=0;break;
		case 3:LSC=1;LSB=0;LSA=1;break;
		case 2:LSC=1;LSB=1;LSA=0;break;
		case 1:LSC=1;LSB=1;LSA=1;break;
	}
	P0=gsmg_code[number];
} 

void smg_display(unsigned int h,min,sec)
{
	shumaguan(1,h/10);
	delay_10us(100);
	shumaguan(2,h%10);
	delay_10us(100);
	
	shumaguan(3,17);   //.
	delay_10us(100);
	
	shumaguan(4,min/10);
	delay_10us(100);
	shumaguan(5,min%10);
	delay_10us(100);
	
	shumaguan(6,17);   //.
	delay_10us(100);
	
	shumaguan(7,sec/10);
	delay_10us(100);
	shumaguan(8,sec%10);
	delay_10us(100);
}



/*************************定时器*******************************/
void time0_init(void)
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1
	TH0=(65535-10000)/256;    
	TL0=(65535-10000)%256;
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器		
}

 void servicetime0() interrupt 1
 {
	 unsigned char count;
	 TH0=(65535-50000)/256;   //重装初值
	 TL0=(65535-50000)%256; 
	 
	 count++;
	 if(count==20)
	 {
		 count=0;
		 sec++;
		 if(sec == 60)
		 {
			 sec=0;
			 min++;
			 if(min == 60)
			 {
				 min=0;
				 h++;
				 if(h == 100)
				 {
					 h=0;
					 min=0;
					 sec=0;
				 }
			 }
		 }
		 
	 }
 }

void main()
{
	time0_init();
	while(1)
	{
		smg_display(h,min,sec);
		 //K1停止记时
        if (KEY1 == 0)
        {
            delay_10us(100);  // 延时消抖
            if (KEY1 == 0)    // 再次检测按键1是否按下
            {
                TR0 = 0;
								while(KEY1 == 0)  
									smg_display(h,min,sec);
								}
            }
        }
			//K2重新开始
				if (KEY2 == 0)
        {
            delay_10us(100);  // 延时消抖
            if (KEY2 == 0)    // 再次检测按键2是否按下
            {
                TR0 = 1;
								while(KEY2 == 0)
								{
									smg_display(h,min,sec);
								}
            }
        }
			//K3秒表清零
				if (KEY3 == 0)
        {
            delay_10us(100);  // 延时消抖
            if (KEY3 == 0)    // 再次检测按键3是否按下
            {
                sec=0;
								min=0;
								h=0;
								TR0 = 0;
							while(KEY3 == 0)
								{
									smg_display(h,min,sec);
								}
            }
        }
	}
}

posted @ 2023-12-07 09:50  Flying3080  Views(83)  Comments(0Edit  收藏  举报  来源