#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint a,b,c,ts,tsd,s,t,s_m,shi,fen,miao;
uint mb_a,mb_b,mb_c,mb_d,mb_e,mb_f;
uint ds_a,ds_b,ds_c,ds_d,ds_e,ds_f;
uchar tt;
sbit zd=P3^2;//中断
sbit lb=P3^7;//闹铃
sbit key1 = P1^3;//模式选择
sbit key2 = P1^4;//调时选择,定时选择,秒表清零
sbit key3=P1^5;//增加数值
sbit key4=P1^0;//闹铃开启
sbit key5=P1^1;//闹铃关闭
uchar table[]={0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,0x80,0x90,0x88,
0x83,0xc6,0xa1,0x86,0x8e};//不带点
uchar smg[8],mb[8],ds[8];
void SZchushihua();
void mbchushihua();
void DSchushihua();
void smg_miao();
void smg_fen();
void smg_shi();
void SZtiaoshi();
void SZtiaoshi_miao();
void SZtiaoshi_fen();
void SZtiaoshi_shi();
void SZmiaobiao();
void mb_haomiao();
void mb_miao();
void mb_fen();
void dingshi();
void DS_miao();
void DS_fen();
void DS_shi();
void qgnaoling();
/*软件延时,约为1ms*/
void delay(uint z)
{
uint i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/*中断定时的初始化*/
void init()
{
EA=1;//打开总中断
TMOD=0x11;//选择仅有TR0/TR1来启动定时器/计数器,定时模式,16位定时器的工作方式
TH0=0xfc;
TL0=0x17;//装初值,定时时间为10ms
ET0=1;//打开定时器0的大门
TH1=0xdc;
TL1=0x00;//装初值,定时时间为50ms
ET1=1;//打开定时器1的大门
IT0=1;//选择电平触发方式,则P3.2口为低电平时有效,也即IE0置1,向CPU申请中断
PT0=1;//定时器0中断定义为高优先级中断。
PT1=1;//定时器1中断定义为高优先级中断。
}
void main()
{
init();
SZchushihua();
mbchushihua();
DSchushihua();
tt=0xfe;
TR0=1;//打开定时器0,开始定时
TR1=1;//打开定时器1,开始定时
while(1)//开始为时钟走时,当按下SP1.3键一次,进入调时,按下两次,进入秒表;
{ //按下三次,进入定时;按下四次,回到时钟;
qgnaoling();
if(key1==0)//按键去抖
{
delay(10);
if(key1==0)
{
b++;
while(!key1);
}
}
if(b==1)//进入调时
{
TR1=0;
if(tsd==1)//调时后回到时钟的控制
{
TR1=1;
}
SZtiaoshi();
}
if(b==2)
{
TR1=0;
a=0; //将a清零,用于秒表的定时初值
s_m=1; //开始扫描秒表
SZmiaobiao();
}
if(b==3)
{
TR1=0;
s_m=2;//开始扫描定时
if(ds_d==1) //进入定时后,经过定时调节后,回到时钟的控制
{
TR1=1;
}
dingshi();
}
if(b==4)
{
s_m=0;
tsd=0;//未进入调时调节的控制,将数码管停止在调时模式
ds_d=0;//未进入定时调节的控制,将数码管停止在定时模式
b=0; //回到时钟模式
TR1=1;
}
if(shi==ds_a && fen==ds_b && miao==ds_c) //闹铃的判断
{
zd=0;
}
}
}
/*时钟模式初始化*/
void SZchushihua()
{
shi=12;
fen=0;
miao=0;
smg[0]=table[shi/10];
smg[1]=table[shi%10];
smg[2]=0xbf;
smg[3]=table[fen/10];
smg[4]=table[fen%10];
smg[5]=0xbf;
smg[6]=table[miao/10];
smg[7]=table[miao%10];
}
/*秒表模式初始化*/
void mbchushihua()
{
mb_a=0;
mb_b=0;
mb_c=0;
mb[0]=table[mb_a/10];
mb[1]=table[mb_a%10];
mb[2]=0xbf;
mb[3]=table[mb_b/10];
mb[4]=table[mb_b%10];
mb[5]=0xbf;
mb[6]=table[mb_c/10];
mb[7]=table[mb_c%10];
}
/*定时模式初始化*/
void DSchushihua()
{
ds_a=6;
ds_b=0;
ds_c=0;
ds[0]=table[ds_a/10];
ds[1]=table[ds_a%10];
ds[2]=0xbf;
ds[3]=table[ds_b/10];
ds[4]=table[ds_b%10];
ds[5]=0xbf;
ds[6]=table[ds_c/10];
ds[7]=table[ds_c%10];
}
/*启动和关闭闹铃程序*/
void qgnaoling()
{
if(key4==0)
{
delay(10);
if(key4==0)
{
EX0=1;//打开中断的大门,允许中断
while(!key4);
}
}
if(key5==0)
{
delay(10);
if(key5==0)
{
EX0=0;//关闭中断的大门,停止中断
while(!key5);
}
}
}
/*定时程序:
当按下SP1.4键一次,按SP1.5键调节秒;
当按下SP1.4键二次,按SP1.5键调节分;
当按下SP1.4键三次,按SP1.5键调节时;
当按下SP1.4键四次,退出定时;
*/
void dingshi()
{
if(key2==0)
{
delay(10);
if(key2==0)
{
ds_f++;
while(!key2);
}
}
while(ds_f==1)
{
if(key2==0)
{
delay(10);
if(key2==0)
{
ds_e++;
while(!key2);
}
}
if(ds_e==0)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
DS_miao();
while(!key3);
}
}
}
if(ds_e==1)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
DS_fen();
while(!key3);
}
}
}
if(ds_e==2)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
DS_shi();
while(!key3);
}
}
}
if(ds_e==3)
{
ds_f=0;
b=3;
ds_d=1;
ds_e=0;
break;
}
}
}
/*时钟调时程序:
当按下SP1.4键一次,按SP1.5键调节秒;
当按下SP1.4键二次,按SP1.5键调节分;
当按下SP1.4键三次,按SP1.5键调节时;
当按下SP1.4键四次,退出调时;
*/
void SZtiaoshi()
{
if(key2==0)
{
delay(10);
if(key2==0)
{
ts=1;
while(!key2);
}
}
while(ts==1)
{
if(key2==0)
{
delay(10);
if(key2==0)
{
s++;
while(!key2);
}
}
if(s==0)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
SZtiaoshi_miao();
while(!key3);
}
}
}
if(s==1)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
SZtiaoshi_fen();
while(!key3);
}
}
}
if(s==2)
{
if(key3==0)
{
delay(10);
if(key3==0)
{
SZtiaoshi_shi();
while(!key3);
}
}
}
if(s==3)
{
ts=0;
b=1;
tsd=1;
s=0;
break;
}
}
}
/*//////////////////////////////////////////////
秒表程序:
按下SP1.5键开始计时,再次按下SP1.5键停止计时
//////////////////////////////////////////////*/
void SZmiaobiao()
{
if(key3==0)
{
delay(5);
if(key3==0)
{
mb_f=1;
mb_d=1;
while(!key3);
}
}
while(mb_f==1)
{
if(key2==0)
{
delay(5);
if(key2==0)
{
mbchushihua();
while(!key2);
}
}
if(key3==0)
{
delay(5);
if(key3==0)
{
mb_d++;
while(!key3);
}
}
if(mb_d==1)
{
TR1=1;
}
if(mb_d==2)
{
TR1=0;
mb_d=0;
}
if(key1==0)
{
delay(5);
if(key1==0)
{
b=3;
while(!key1);
}
break;
}
}
}
/*中断程序:
用于闹铃的响和停,一共响1分钟,在一分钟内,按下SP1.5键,则停止闹铃*/
void Zduan() interrupt 0
{
uint nl;
for(nl=0;nl<2728;nl++)
{
lb=0;
delay(10);
lb=1;
delay(10);
if(key5==0)
{
delay(10);
if(key5==0)
{
EX0=0;
while(!key5);
}
break;
}
}
zd=1;
}
/*扫描程序:
用于数码管的显示*/
void Dsqi0() interrupt 1 //约1ms
{
TH0=0xfc;
TL0=0x17;
P2=0xff;
if(s_m==0)//时钟的扫描
{
P0=smg[c];
P2=tt;
tt=_crol_(tt,1);
c=c+1;
c=c&0x07;
}
if(s_m==1)//秒表的扫描
{
P0=mb[c];
P2=tt;
tt=_crol_(tt,1);
c=c+1;
c=c&0x07;
}
if(s_m==2)//定时的扫描
{
P0=ds[c];
P2=tt;
tt=_crol_(tt,1);
c=c+1;
c=c&0x07;
}
}
/*用于时钟的定时和秒表的定时*/
void dingshiqi_1() interrupt 3
{
TH1=0xdc;
TL1=0;
a++;
if(a>=100 && s_m==0) //时钟的定时,1秒
{
a=0;
smg_miao();
}
if(a==1 && s_m==1)//秒表的定时,10ms
{
a=0;
mb_haomiao();
}
}
/*时钟调时的调秒程序*/
void SZtiaoshi_miao()
{
miao++;
if(miao>59)
{
miao=0;
}
smg[6] = table[miao/10];
smg[7] = table[miao%10];
}
/*时钟调时的调分*/
void SZtiaoshi_fen()
{
fen++;
if(fen>59)
{
fen=0;
}
smg[3]=table[fen/10]; // 分十位
smg[4]=table[fen%10]; // 分个位
}
/*时钟调时的调时*/
void SZtiaoshi_shi()
{
shi++;
if(shi>23)
{
shi=0;
}
if(shi>9)
smg[0]=table[shi/10];// 时十位
else
smg[0]=0xff;// 当小时的十位为0时不显示
smg[1]=table[shi%10];//时个位
}
/*时钟的显示——秒*/
void smg_miao()
{
miao++;
if(miao>59)
{
miao=0;
smg_fen();
}
smg[6]=table[miao/10];
smg[7]=table[miao%10];
}
/*时钟的显示——分*/
void smg_fen()
{
fen++;
if(fen>59)
{
fen=0;
smg_shi();
}
smg[3]=table[fen/10];//分十位
smg[4]=table[fen%10];//分�