![](http://tiebapic.baidu.com/forum/w%3D580/sign=8e9388619bc451daf6f60ce386fd52a5/dd5cd7889e510fb39a6267a89f33c895d1430c2c.jpg?tbpicau=2024-09-02-05_41276d70fbeac90668798194c6949ed6)
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P1^0;//蜂鸣器
sbit key1=P1^1;//功能切换.时间/闹钟
sbit key2=P1^2;//选择时、分、秒(按第4次确认)
sbit key3=P1^3;//加
sbit key4=P1^4;//减
sbit key5=P1^5;//停止响铃
u8 mode=0;//模式。0时间1闹钟
u8 cixu=0;//设置模式。1时2分3秒
u8 time=0;//计时变量,1s
u8 beep_flag=0,beep_flag0=0;//蜂鸣器标志
u8 xian1[8]={0,0,0x40,0,0,0x40,0,0};//显存.时间
u8 xian2[8]={0,0,0x40,0,0,0x40,0,0};//显存。闹钟
u8 shi=0,fen=0,miao=0;//时间
u8 shi0=0,fen0=0,miao0=30;//闹钟
u8 code smgduan0[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9,无小数点
u8 code smgduan1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//显示0~9,有小数点
void delay(u16 i)//延时
{
while(i--);
}
void display1()//显示时间
{
if((cixu==1)&&(time<50))
{
P0=0;
P2=0x7f;
delay(100);
P0=0;
P2=0xbf;
delay(100);
}
else
{
P0=0;
P2=0x7f;
P0=smgduan0[xian1[0]];//时
delay(100);
P0=0;
P2=0xbf;
P0=smgduan0[xian1[1]];//时
delay(100);
}
P0=0;
P2=0xdf;
P0=0x40;//-
delay(100);
if((cixu==2)&&(time<50))
{
P0=0;
P2=0xef;//分
delay(100);
P0=0;
P2=0xf7;//分
delay(100);
}
else
{
P0=0;
P2=0xef;
P0=smgduan0[xian1[3]];//分
delay(100);
P0=0;
P2=0xf7;
P0=smgduan0[xian1[4]];//分
delay(100);
}
P0=0;
P2=0xfb;
P0=0x40;//-
delay(100);
if((cixu==3)&&(time<50))
{
P0=0;
P2=0xfd;
delay(100);
P0=0;
P2=0xfe;//秒
delay(100);
}
else
{
P0=0;
P2=0xfd;
P0=smgduan0[xian1[6]];//秒
delay(100);
P0=0;
P2=0xfe;
P0=smgduan0[xian1[7]];//秒
delay(100);
}
}
void display2()//显示闹钟
{
if((cixu==1)&&(time<50))
{
P0=0;
P2=0x7f;
delay(100);
P0=0;
P2=0xbf;
delay(100);
}
else
{
P0=0;
P2=0x7f;
P0=smgduan0[xian2[0]];//时
delay(100);
P0=0;
P2=0xbf;
P0=smgduan0[xian2[1]];//时
delay(100);
}
if((cixu==2)&&(time<50))
{
P0=0;
P2=0xef;//分
delay(100);
P0=0;
P2=0xf7;//分
delay(100);
}
else
{
P0=0;
P2=0xef;
P0=smgduan0[xian2[3]];//分
delay(100);
P0=0;
P2=0xf7;
P0=smgduan0[xian2[4]];//分
delay(100);
}
if((cixu==3)&&(time<50))
{
P0=0;
P2=0xfd;
delay(100);
P0=0;
P2=0xfe;//秒
delay(100);
}
else
{
P0=0;
P2=0xfd;
P0=smgduan0[xian2[6]];//秒
delay(100);
P0=0;
P2=0xfe;
P0=smgduan0[xian2[7]];//秒
delay(100);
}
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XD8;//给定时器赋初值,定时10ms
TL0=0XF0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Timer0Init(); //定时器0初始化
xian1[0]=shi/10;//计算到显存
xian1[1]=shi%10;
xian1[3]=fen/10;
xian1[4]=fen%10;
xian1[6]=miao/10;
xian1[7]=miao%10;
xian2[0]=shi0/10;
xian2[1]=shi0%10;
xian2[3]=fen0/10;
xian2[4]=fen0%10;
xian2[6]=miao0/10;
xian2[7]=miao0%10;
while(1)
{
if(mode)
display2();//显示闹钟
else
display1();//显示时间
if(!key1 &&(cixu==0))//功能切换
{
mode=!mode;
while(!key1);
}
if(!key2)//选择
{
if(cixu<3)
cixu++;
else
cixu=0;
while(!key2);
}
if(!key3)//加
{
if(mode==0)
{
switch(cixu)
{
case 1:
if(shi<23)
shi++;
break;
case 2:
if(fen<59)
fen++;
break;
case 3:
if(miao<59)
miao++;
}
}
else
{
switch(cixu)
{
case 1:
if(shi0<23)
shi0++;
break;
case 2:
if(fen<59)
fen0++;
break;
case 3:
if(miao0<59)
miao0++;
}
}
xian1[0]=shi/10;//计算到显存
xian1[1]=shi%10;
xian1[3]=fen/10;
xian1[4]=fen%10;
xian1[6]=miao/10;
xian1[7]=miao%10;
xian2[0]=shi0/10;
xian2[1]=shi0%10;
xian2[3]=fen0/10;
xian2[4]=fen0%10;
xian2[6]=miao0/10;
xian2[7]=miao0%10;
while(!key3);
}
if(!key4)//减
{
if(mode==0)
{
switch(cixu)
{
case 1:
if(shi>0)
shi--;
break;
case 2:
if(fen>0)
fen--;
break;
case 3:
if(miao>0)
miao--;
}
}
else
{
switch(cixu)
{
case 1:
if(shi0>0)
shi0--;
break;
case 2:
if(fen0>0)
fen0--;
break;
case 3:
if(miao0>0)
miao0--;
}
}
xian1[0]=shi/10;//计算到显存
xian1[1]=shi%10;
xian1[3]=fen/10;
xian1[4]=fen%10;
xian1[6]=miao/10;
xian1[7]=miao%10;
xian2[0]=shi0/10;
xian2[1]=shi0%10;
xian2[3]=fen0/10;
xian2[4]=fen0%10;
xian2[6]=miao0/10;
xian2[7]=miao0%10;
while(!key4);
}
if(!key5)//停止响铃
{
beep_flag=0;
beep=1;
while(!key5);
}
if((shi==shi0)&&(fen==fen0)&&(miao==miao0))//判断响铃
{
beep_flag=1;
beep=0;
}
}
}
/*******************************************************************************
* 函 数 名 : void Timer0() interrupt 1
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer0() interrupt 1
{
TH0=0XD8;//给定时器赋初值,定时10ms
TL0=0XF0;
if(time<100) //1s
time++;
else
{
time=0;
if(((cixu==0)&&(mode==0))||(mode==1))
{
if(miao<59) //秒
miao++;
else
{
miao=0;
if(fen<59) //分
fen++;
else
{
fen=0;
if(shi<23) //时
shi++;
else
shi=0;
}
}
}
xian1[0]=shi/10;//计算到显存
xian1[1]=shi%10;
xian1[3]=fen/10;
xian1[4]=fen%10;
xian1[6]=miao/10;
xian1[7]=miao%10;
}
if(beep_flag)//蜂鸣器控制
{
if(time==0)
{
beep=!beep;
beep_flag0=!beep_flag0;
if(beep_flag<7)//延时6s
beep_flag++;
else
{
beep_flag=0;
beep=1;
}
}
}
}