Bootstrap

51单片机应用开发(进阶)---定时器应用(电子秒表)

实现目标

1、巩固定时器的配置流程;

2、掌握按键、数码管与定时器配合使用;

3、秒表具体实现:(1)按K1开始计时,再按K1暂停计时.......;(2)按K2计时清零;(3)数码管显示四位数字(前两位秒,后两位10ms+1)。


一、秒表

电子秒表(Cronometro)是一种较先进的电子计时器,具有高精度、多功能和易操作等特点。以下是关于电子秒表的详细介绍:

1.1、基本功能与特点

  1. 显示功能:电子秒表不仅能显示分、秒,还能显示时、日、月及星期,部分型号甚至能精确到小数点后两位。
  2. 计时功能:一般的电子秒表连续累计时间为59min 59.99s,可读到1/100s,平均日差±0.5s。它配有三个按钮,通常包括秒表按钮、功能变换按钮和调整按钮,用户可以通过这些按钮轻松实现计时、停止、复零等功能。
  3. 双计时功能:部分电子秒表还具备双计时功能,适用于需要同时记录两个不同时间点的场景。

1.2、工作原理

电子秒表通过利用电子元件(如振荡器、定时器、计数器和显示器等)来实现时间的准确测量。

  1. 振荡器:产生稳定的时间基准信号,通常为1赫兹(即每秒钟产生一个周期)。
  2. 定时器与计数器:定时器设置一个初始值后开始计时,同时计数器开始累加时间基准信号的周期数。
  3. 计算与显示:当定时器达到设置的目标值时,发送触发信号停止计时器,并记录下计数器的值。最后,通过显示器以数字形式显示时间测量结果。

1.3、使用方法

电子秒表的使用方法通常包括以下几个步骤:

  1. 开始计时:按下秒表按钮(通常是右侧按钮)开始自动计秒。
  2. 停止计时:再次按下秒表按钮停止计秒,此时显示器上会显示所计的数据。
  3. 复零:按住某个按钮(通常是左侧按钮)两秒钟左右,秒表会自动复零,恢复到初始状态。
  4. 功能变换与调整:通过功能变换按钮和调整按钮,用户可以在不同的显示模式之间进行切换,并对时间、日期等进行校正与调整。

1.4、应用领域

由于电子秒表具有精确度高、操作简便等优点,它被广泛应用于各种领域:

  1. 体育比赛:用于记录运动员的比赛成绩。
  2. 实验研究:在科学实验和研究中,用于精确测量时间间隔。
  3. 日常生活:如烹饪、健身、学习等场景中,帮助人们更好地管理时间。

二、原理图设计

 

三、程序设计

#include <REGX52.H>
 
//定义数码管位选信号控制脚
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
 
sbit K1 = P3^1;//按键K1
sbit K2 = P3^0;//按键K2
 
char  num = 0;//计数值 
char  S   = 0; //秒计数
 
 
//共阴极数码管显示0~F - 的段码数据
unsigned char gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
				0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
 
void delay_10us(int ten_us)
{
	while(ten_us--);	
}

 
unsigned int g_Count;  //全局变量默认初始化为0
 
void Timer0_Init(void)
{
    TMOD = 0x01; //设置定时器0 工作模式1    0000  0001
    TR0 = 0;     //先关闭定时器0
    TH0 = (65536-1000)/256;  //设置定时初值,高8位
    TL0 = (65536-1000)%256;  //设置定时初值,低8位
    ET0 = 1;  //开启定时器0 中断
	EA  = 1;  //开启总中断
}
 
void main(void)
{
	Timer0_Init();  //定时器0初始化
	while(1)
	{
	   	LSC=1;LSB=1;LSA=1;
		P0 = gsmg_code[S/10];
		delay_10us(5);
		P0 = 0x00;//消影
		
	   	LSC=1;LSB=1;LSA=0;
		P0 = gsmg_code[S%10];		
		delay_10us(5);
		P0 = 0x00;//消影
		
	   	LSC=1;LSB=0;LSA=1;
		P0 = gsmg_code[16];
		delay_10us(5);
		P0 = 0x00;//消影
		
	   	LSC=1;LSB=0;LSA=0;
		P0 = gsmg_code[num/10];		
		delay_10us(5);
		P0 = 0x00;//消影	

		LSC=0;LSB=1;LSA=1;
		P0 = gsmg_code[num%10];
		delay_10us(5);
		P0 = 0x00;//消影
		
		if(K1 == 0)//如果按键K1按下
		{
			while(!K1);//松手检测
			TR0 = !TR0;
		
		}
		if(K2 == 0)//如果按键K2按下
		{
			while(!K2);//松手检测
			num = 0;
			S = 0;
		}	

	}
}
 
void Timer0_Rountine(void) interrupt 1  //1ms进一次中断
{
    TH0 = (65536-1000)/256;  //
    TL0 = (65536-1000)%256;  //重新赋初值才能保证下一次还是1ms
	  
    g_Count++;
    if(g_Count>=10)  // 10ms 计时
	{
		g_Count = 0;   //计数清零
		num++;
		if(num > 99)//1s
		{
			num = 0;
			S++;
			if(S > 99)//99s
			{
				S = 0;
			}
		}	
	}
}



四、实验效果

五、仿真实现


总结

;