/*通過獨立鍵控制調節的時鍾。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;
}