刚用AT89C52做了个计时器。能够精确到10ms位,并且具有手动启停,归零功能。
下面是Proteus实现视图
下面是其C51实现代码:
#include<stdio.h>
#include<reg51.h>
int h1,h2,m1,m2,s1,s2,hs1,hs2;
int h,m,s,hs;
int dis[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char stop; // 1 表示现在为停状态, 0 表示现在为运行状态
char cl=0; // 1 表示Clear键按下
sbit Start_stop=P3^2; //暂停、启动键, 0 时有效
sbit Clear=P3^3; //清除键,0 时有效
void Delay5();
void Display();
void main()
{
TMOD=0x11;
TH1=0xd8; //硬件10ms计时
TL1=0xf5;// TL1=0xf0;
TF1=0;
TF0=0;
stop=1;
TR1=0; //关T1中断
TR0=0; //关闭T0
ET0=0; // 禁用T0中断
ET1=1; //允许T1中断
EX0=1; //允许外0中断
EX1=1; //允许外1中断
//置优先级
PX0=1;
PX1=1;
PT1=0;
IT1=0;
IT0=0;
EA=1; // 中断允许
P3=0xff; //使 P3 输出高电平
P1=dis[0]; //初始化,使其输出全 O
P2=0x00;
while(1)
{
Display();
}
}
void Delay5() //延时 5ms
{
int i;
for(i=5;i>0;i--)
;
}
void Display()
{
h1=h/10;
h2=h;
P2=0xff; //显示时
P1=dis[h1];
P2=0xfe;
Delay5();
P2=0xff;
P1=dis[h2]|0x80;
P2=0xfd;
m1=m/10;
m2=m;
// Delay5(); //显示分
P2=0xff;
P1=dis[m1];
P2=0xfb;
Delay5();
P2=0xff;
P1=dis[m2]|0x80;
P2=0xf7;
s1=s/10;
s2=s;
// Delay5(); //显示秒
P2=0xff;
P1=dis[s1];
P2=0xef;
Delay5();
P2=0xff;
P1=dis[s2]|0x80;
P2=0xdf;
hs1=hs/10;
hs2=hs;
// Delay5(); //显示毫秒
P2=0xff;
P1=dis[hs1];
P2=0xbf;
Delay5();
P2=0xff;
P1=dis[hs2];
P2=0x7f;
Delay5();
}
void start_stop(void) interrupt 0 using 3 //外部中断 0 ,暂停/启动键,0 时有效
{
TR1=0;
if(stop==0) //运行状态
{
stop=1;
TR1=0;
}
else //暂停状态
{
if(!cl%2)
{
stop=0;
TH1=0xd8; //硬件10ms计时
TL1=0xf0; // TL1=0xf0;
TR1=1;
}
}
}
void clear(void) interrupt 2 using 2 //外部中断 1 ,清除键,0 时有效
{
TR1=0;
cl++;
if(stop==1) //暂停态
{
if(cl%2) //cl 单数次按下,则清零,,并cl归0
{
cl=0;
h=0;
m=0;
s=0;
hs=0;
}
else //cl 偶数次按下,则开始计时,并cl归0
{
cl=0;
stop=0;
TH1=0xd8; //硬件10ms计时
TL1=0xf0; // TL1=0xf0;
TR1=1;
}
}
else //运行态
{
stop=1;
TR1=0;
}
}
void t1(void) interrupt 3 using 1 //计时器 1 中断
{
TH1=0xd8; //硬件10ms计时
TL1=0xf5; // TL1=0xf0;
TR1=1;
hs++;
if(hs==100) {
hs=0;s++; //够100毫秒则秒计数加1,毫秒清零
}
else if(s==60){
s=0;m++;//够1分钟则分钟计数加1
}
else if(m==60){
m=0;h++;///够1小时则小时计数加1
}
else if(h==24){
h=0;//够24小时则清零
}
}