设计思路:
每次key1按键按下,秒表在启动/暂停之间切换;
每次key2按键按下,秒表清零并暂停;
秒表显示目前记录的秒数,启动时,每秒加1,暂停时显示无变化;
达到60秒后,LED提示灯闪烁三次,之后自动切换为00,并重新计时。
仿真元器件清单:
7SEG-COM-CATHODE
AT89C51
BUTTON
CAP
CRYSTAL
RES
RESPACK-7
LED
实现程序:
#include<reg51.h>
unsigned char duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit key1=P1^0;
sbit key2=P1^1;
sbit led=P3^0;
bit run;
unsigned char count,j;
unsigned char count,i;
void delay(unsigned int z)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}
void main()
{
P0=0;
P2=0;
key1=1;
key2=1;
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
while(1)
{
if(key1==0)
{
run=1;
}
else if(key2==0)
{
run=0;
count=0;
}
if(run)
{ if(key1==0)
{
TR0=~TR0;
while(!key1);
}
}
else
{
TR0=0;
P0=duan[0];
P2=duan[0];
}
}
}
void time0()interrupt 1
{
i++;
if(i==20)
{
i=0;
count++;
if(count>=60)
{
P0=duan[6];
P2=duan[0];
delay(1000);
count=0;
P0=duan[0];
P2=duan[0];
TR0=1;
for(j=0;j<6;j++)
{
led=~led;
delay(500);
}
}
P0=duan[count/10];
P2=duan[count%10];
}
TH0=0x3c;
TL0=0xb0;
}
实现仿真图:
实现效果视频:
进阶版(转载):
达到60秒后,LED提示灯闪烁三次,每次0.5*2。并不会影响计时和显示的正常节奏。
7SEG-COM-CATHODE替换为7SEG-MPX1-CA
程序为
#include<reg51.h>
sbit LED=P1^0;
sbit KEY1=P3^2; //启动/暂停按键
sbit KEY2=P3^3; //清零按键
unsigned char duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char miao,i,half_miao;flag;
void main()
{
KEY1=1;KEY2=1;TR0=0; LED=1;miao=0;half_miao=0;flag=10;//设置初始状态
TMOD=0x11;
TH0=(65536-50000)/256; //设置50ms定时的初始值
TL0=(65536-50000)%256;
EA=1; ET0=1;EX0=1;EX1=1;//开启中断
PX0=1;PX1=1; //确保外部按键中断优先于定时器
P0=duan[miao/10]; //显示时间初始值
P2=duan[miao%10];
while(1); //无限循环,交给中断自行处理
}
void int0() interrupt 0 //按键1产生外部中断0
{
TR0=~TR0;// 外部中断0 在启动or暂停之间切换
}
void int1() interrupt 1 //定时计数器0 每50ms
{
i++; //50ms计数值加1
if(i==10) //每10次 0.5s
{
i=0; //计数值归0
half_miao++; //0.5s记录值加1
if(half_miao%2==0) //0.5s记录值为偶数,即每1s
miao++;
P0=duan[miao/10]; //显示新的时间
P2=duan[miao%10];
if(miao==60) //60秒时
{
miao=0; //时间清0
flag=0; //将闪烁标志数从初值10改为0,准备开启闪烁
}
switch(flag)
{ case 0:LED=0;break;
case 1:LED=1;break;
case 2:LED=0;break;
case 3:LED=1;break;
case 4:LED=0;break;
case 5:LED=1;break;
default:break;
}
if(flag<6) flag++; //在闪烁期间,每50ms将闪烁标志数增加1
}
TH0=(65536-50000)/256; //每次计数循环都需要重新设置50ms定时的初始值
TL0=(65536-50000)%256;
}
void int2() interrupt 2 //按键2清零
{
miao=0;
half_miao=0;
}
仿真图:
实现效果视频
Comments NOTHING