实现目标
1、巩固定时器的配置流程;
2、掌握按键、数码管与定时器配合使用;
3、秒表具体实现:(1)按K1开始计时,再按K1暂停计时.......;(2)按K2计时清零;(3)数码管显示四位数字(前两位秒,后两位10ms+1)。
一、秒表
电子秒表(Cronometro)是一种较先进的电子计时器,具有高精度、多功能和易操作等特点。以下是关于电子秒表的详细介绍:
1.1、基本功能与特点
- 显示功能:电子秒表不仅能显示分、秒,还能显示时、日、月及星期,部分型号甚至能精确到小数点后两位。
- 计时功能:一般的电子秒表连续累计时间为59min 59.99s,可读到1/100s,平均日差±0.5s。它配有三个按钮,通常包括秒表按钮、功能变换按钮和调整按钮,用户可以通过这些按钮轻松实现计时、停止、复零等功能。
- 双计时功能:部分电子秒表还具备双计时功能,适用于需要同时记录两个不同时间点的场景。
1.2、工作原理
电子秒表通过利用电子元件(如振荡器、定时器、计数器和显示器等)来实现时间的准确测量。
- 振荡器:产生稳定的时间基准信号,通常为1赫兹(即每秒钟产生一个周期)。
- 定时器与计数器:定时器设置一个初始值后开始计时,同时计数器开始累加时间基准信号的周期数。
- 计算与显示:当定时器达到设置的目标值时,发送触发信号停止计时器,并记录下计数器的值。最后,通过显示器以数字形式显示时间测量结果。
1.3、使用方法
电子秒表的使用方法通常包括以下几个步骤:
- 开始计时:按下秒表按钮(通常是右侧按钮)开始自动计秒。
- 停止计时:再次按下秒表按钮停止计秒,此时显示器上会显示所计的数据。
- 复零:按住某个按钮(通常是左侧按钮)两秒钟左右,秒表会自动复零,恢复到初始状态。
- 功能变换与调整:通过功能变换按钮和调整按钮,用户可以在不同的显示模式之间进行切换,并对时间、日期等进行校正与调整。
1.4、应用领域
由于电子秒表具有精确度高、操作简便等优点,它被广泛应用于各种领域:
- 体育比赛:用于记录运动员的比赛成绩。
- 实验研究:在科学实验和研究中,用于精确测量时间间隔。
- 日常生活:如烹饪、健身、学习等场景中,帮助人们更好地管理时间。
二、原理图设计
三、程序设计
#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;
}
}
}
}