利用51单片机制作秒表主要用到:定时器部分、延时函数模块、数码管的显示,并结合一些简单的程序来实现。我这边只是实现简单的倒计时,与手机计时器的演示一致。
1.
定时计数器的常用场合
单片机的定时器计数器常做以下方面的应用:
定时功能。例如要每
10ms
检测一次
IO
口的电平,可以使用定时器设定
10ms
的定时并产生中断,在
中断里边检测
IO
口的电平。因为定时器的运行时不依赖于
CPU
的,所以这样可以大大减小
CPU
的负载。
计数功能。例如要检测某个外部脉冲的时长,则可以在检测到上升沿的时候启动定时器计数器并记
录当前值
A
,在检测到下降沿的时候停止定时计数器并记录当前值
B
,这时候查
A
和
B
的差,就可以
推算出外部脉冲的时长。
2.
单片的定时计数器
51
单片机的定时计数器和上述的定时器计数器的原理是一样,
51
单片机一共有
2
个独立的定时计数器
T0 和T1.
每个计数器是由
2
个
8
位的寄存器组成的(一共
16位),
定时计数器是通过
TCON
和
TMOD
两个寄存器进行配置的,通过这两个寄存器,可以配置计数器的初值,配置是否产生中断,定时器计数器的工作模式。下面只介绍了两种工作方式
工作方式
0
:只使用
13
位计数器,最大计数值为
8191
,不建议使用这个工作方式
工作方式
1
:则使用
16
位计数器,最大计数值为
65535
,这种工作方式最常用
3.TCON
寄存器
如图
所示,
TCON
寄存器用来启动定时器或者记录定时器是否有溢出
TR0
位
该位控制
T0
定时计数器的启动或者停止,
TR0 =1
时,
T0
定时计数器启动
; TR0 =1时,
T0
定时计数器停止。
TF0
位
该位记录
T0
定时计数器是否有溢出
,如果有溢出则该位是
1
,还未溢出 则为0
TR1
和
TF1
TR1
控制定时计数器
1
的启动或者停止;
TF1
记录定时计数器
T1
是否有溢出。
因为我使用的是定时器0的工作方式
,所以不是
T0
的部分全部写
0
即可,根据下图的值转换为对应的16
进制,
TMOD
的值应该为
0x01。
4、根据定时器的使用步骤,首先要设置定时器的工作模式,这里使用定时计数器
T0
实现秒表功能
工作方式为
1
,所有
M1M0 = 01
使用定时模式,所有
C/T = 0
只需要软件启动定时器,所有
GATE = 0
对应到
TMOD
寄存器如图
2-5-10
所示,因为我们使用的是
T0
,所以不是
T0
的部分全部写
0
即可,根
据图上的值转换为对应的
16
进制,
TMOD
的值应该为
0x01
主要是结合4位数码管的相关代码的基础上编译的程序代码:
#include "regx52.h"
#include "intrins.h"
#include "SMG.h"
unsigned int second = 0;
void main()
{
TMOD = 0x01;
TH0 = 0xB7;
TL0 = 0xFF;
ET0 = 1;
EA = 1;
TR0 = 1;
while(1)
{
Show_Num(second);
}
}
void time0() interrupt 1
{
static unsigned int i;
TH0 = 0xB7;
TL0 = 0xFF;
i++;
if(i==50)
{
i = 0;
second++;
}
}
以上是main.c的主要代码程序,如有问题请提出来一起讨论,或有错误我将及时更正。
以下是delay.c延时函数模块的代码:
#include "delay.h"
#include "intrins.h"
void Delay1_ms(unsigned int a)
{
unsigned char i, j;
for(a;a>0;a--)
{
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
以下是delay.h延时函数的程序代码:
#ifndef _DELAY_H
#define _DELAY_H
void Delay1_ms(unsigned int a);
#endif