/*通过独立键控制调节的时钟。s2控制启动;s3控制暂停;s4控制在暂停的状态下切换时针、分针;s5控制时针、分针的值的增加*/
/* 其中优化完善的功能是:在切换时针、分针的状态下,其数码管能闪烁显示数字*/
#include <reg52.h>
#include <intrins.h>
//宏定义
#define uchar unsigned char
#define uint unsigned int
//数码管显示数字赋值初始化
uchar code leddate[]={
0X3f,//0
0X06,//1
0X5B,//2
0X4f,//3
0X66,//4
0X6d,//5
0X7d,//6
0X07,//7
0X7f,//8
0X6f, //9
0Xbf,//0.
0X86,//1.
0Xdb,//2.
0Xcf,//3.
0Xe6,//4.
0Xed,//5.
0Xfd,//6.
0X87,//7.
0Xff,//8.
0Xef //9.
};
sbit LED1=P1^0;
sbit wei=P2^7;
sbit duan=P2^6;
sbit s2=P3^0;//启动计时
sbit s3=P3^1;//暂停计时
sbit s4=P3^2;//切换分针、时针调节位
sbit s5=P3^3;//分针或时针 加一
uchar t=0;
uchar s=0;
uchar m=0;
uchar h=0;
uchar te=0;
uchar temp=0; //实现闪烁功能的数值,每temp加一,其数值闪烁一次
//延时
void delay(uchar z){
uchar x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--)
_nop_();
}
//定时器初始化
void T_reput(){
TMOD = 0X11;
TH0=0X4b;
TL0=0Xfd;
TH1=0X4b;
TL1=0Xfd;
EA=1;//系统开放中断
ET0=1;//允许T0中断
ET1=1;//允许T1中断
TR0=1;//启动时钟 0
TR1=1;//启动时钟1
}
//秒针
void miao(uchar z){
uchar shi,ge;
shi= z/10;//求模
ge= z%10;//求余
P0=0Xff;//在位打开之前,先将前一次的P0值(段)清零
wei=1; //开启位选开关
P0=0X7f;
wei=0; //关闭位选开关
duan=1; //开启段选开关
P0=leddate[ge];
duan=0; //关闭段开关
delay(1); //正常刷新延时
P0=0Xff;
wei=1;
P0=0Xbf;
wei=0;
duan=1;
P0=leddate[shi];
duan=0;
delay(1);
}
//分针
void fen(uchar z){
uchar shi,ge;
shi= z/10;
ge= z%10;
P0=0Xff;
wei=1;
P0=0Xdf;
wei=0;
duan=1;
P0=leddate[ge+10];
duan=0;
delay(1);
P0=0Xff;
wei=1;
P0=0Xef;
wei=0;
duan=1;
P0=leddate[shi];
duan=0;
delay(1);
}
//时针
void hour(uchar z){
uchar shi,ge;
shi= z/10;
ge= z%10;
P0=0Xff;
wei=1;
P0=0Xf7;
wei=0;
duan=1;
P0=leddate[ge+10];
duan=0;
delay(1);
P0=0Xff;
wei=1;
P0=0Xfb;
wei=0;
duan=1;
P0=leddate[shi];
duan=0;
delay(1);
}
//实现分针、时针调节以及数值闪烁的功能模块
void adjust(){
delay(5);
while(!s4); //按键检测
while(1){
if(s2 == 0 || s3 == 0)
break;
//进入时针数字调节环节
while(1){
if(1 == (temp % 2))//实现数码管数字闪烁的关键语句,此处实现时针闪烁
break;
miao(s);
fen(m);
hour(h);
if(s5 == 0){
delay(5);//软件防抖
if(h<23)
h++;
while(!s5);//按键检测
}
if(s2 == 0 || s3 == 0)
break;
if(s4 == 0){
while(!s4);
//进入分针数字调节环节
while(1){
if(s2 == 0 || s3 == 0)
break;
if(s4 == 0){
while(!s4);
break; //退出分针数字调节环节
}
while(1){
if(1 == (temp % 2))//实现数码管数字闪烁的关键语句,此处实现分针闪烁
break;
miao(s);
fen(m);
hour(h);
if(s5 == 0){
delay(5);
if(m<59)
m++;
while(!s5);
}
if(s4 == 0){
break; //退出分针数字调节环节
}
if(s2 == 0 || s3 == 0)
break;
}
//分针数码管数字闪烁
while(1){
if(0 == (temp % 2))
break;
miao(s);
hour(h);
if(s5 == 0){
delay(5);
if(m<59)
m++;
while(!s5);
}
if(s4 == 0){
break; //退出分针数字调节环节
}
if(s2 == 0 || s3 == 0)
break;
}
}
//退出分钟数字调节环节
}
}
//时针数码管数字闪烁
while(1){
if(0 == (temp % 2))
break;
miao(s);
fen(m);
if(s5 == 0){
delay(5);//软件防抖
if(h<23)
h++;
while(!s5);//按键检测
}
if(s2 == 0 || s3 == 0)
break;
if(s4 == 0){
while(!s4);
//进入分针数字调节环节
while(1){
if(s2 == 0 || s3 == 0)
break;
if(s4 == 0){
while(!s4);
break; //退出分针数字调节环节
}
while(1){
if(1 == (temp % 2))
break;
miao(s);
fen(m);
hour(h);
if(s5 == 0){
delay(5);
if(m<59)
m++;
while(!s5);
}
if(s4 == 0){
break; //退出分针数字调节环节
}
if(s2 == 0 || s3 == 0)
break;
}
//分针数码管数字闪烁
while(1){
if(0 == (temp % 2))
break;
miao(s);
hour(h);
if(s5 == 0){
delay(5);
if(m<59)
m++;
while(!s5);
}
if(s4 == 0){
break; //退出分针数字调节环节
}
if(s2 == 0 || s3 == 0)
break;
}
}
//退出分针数字调节环节
}
}
}
}
void main(){
T_reput();//定时器初始化
while(1){
if(s < 60){
miao(s);
}else{
s=0;
m++;
}
if(m<60){
fen(m);
}else{
m=0;
h++;
}
if(h<24){
hour(h);
}else{
h=0;
}
if(s2 == 0)
TR0=1; //启动计时
if(s3 == 0)
TR0=0; //暂停计时
if(TR0 == 0){
if(s4 == 0){
delay(5);
adjust();
}
}
}
}
//T0中断服务函数
void T0_ISR() interrupt 1{
TH0=0X4b;
TL0=0Xfd;
t++;
if(t == 20){
t=0;
s++;
LED1=~LED1;
}
}
//T1中断服务函数
void T1_ISR() interrupt 3{
TH1=0X4b;
TL1=0Xfd;
te++;
if(te == 13){
te=0;
temp++;
}
if(temp == 100)
temp=0;
}