📄 clock.c
字号:
/////////// 完整
#include<absacc.h>
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define COM8155 XBYTE[0x8000]
#define PA8155 XBYTE[0x8001]
#define PB8155 XBYTE[0x8002]
#define PC8155 XBYTE[0x8003]
//全局变量
uint dis[6];
uint date[3]={84,29,11}; //年,日,月
uint time[3]={23,59,50}; //时,秒,分
uint alarm[3]={6,160,30}; //时,开关,分
uint stop_w[3]={0,0,0}; //分,毫秒,秒
uint counter=20;
bit O_DOT;
bit DOT;
bit leap; //闰年标志
bit alarm1;
uint set;
uint *exch; //交换显示指针
sbit buzzer=P1^3;
uint st[21]={0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,
0xff,0xc,0x89,0x7f,0xbf}; // 字型码
//判键显示子程序
void process(uint key_vl);
void delay(uint i);
uint scan(void);
uint f_key(void);
void display(void);
void dvid(uint *p);
void timer(void);
void fun(uint set);
void time_m(void);
void data_m(void);
void leap_y(void);
uint dpm(void); //每月天数判断
void arm_c(void);
/// 定时器0 用于计时/////////
void timer0() interrupt 1 using 1
{
TH0=0x3C;
TL0=0xB;
counter=counter-1;
if(counter==0)
{
counter=20;
timer();
DOT=!DOT;
}
}
/// 中断1 用于秒表/////////
void timer1() interrupt 3 using 2
{
if(stop_w[1]==99)
{
stop_w[1]=0;
if(stop_w[2]==59)
{
stop_w[2]=0;
stop_w[0]=stop_w[0]+1;
}
else
stop_w[2]=stop_w[2]+1;
}
else
stop_w[1]=stop_w[1]+1;
}
////////// 主函数 ////////////
void main()
{
uint i;
uint idata key_vl=0xff;
O_DOT=1;
DOT=1;
alarm1='0';
for(i=0;i<6;i++)
dis[i]=0; ////初始化显示缓冲区
COM8155=0x3; // 初始化LED
exch=time;
set=0;
EA=1;
TMOD=0x1;
TH0=0x3C;
TL0=0xB;
ET0=1;
TR0=1; // 定时器 0
TH1=0xd8;
TL1=0xf;
ET1=1;
TR1='0'; //定时器 1
delay(200);
while(1)
{
arm_c();
key_vl=scan();
process(key_vl);
dvid(exch);
display();
}
}
/// 键处理 ////////
void process(uint key_vl)
{
switch(key_vl)
{
case 0xff:
break;
case 12:
set=set+1;
if(set==4)
set=0;
switch(set)
{
case 0: exch=time;break;
case 1: exch=date;break;
case 2: exch=stop_w;break;
case 3: exch=alarm;break;
default: break;
}
break;
case 10:
fun(set); break;
default:
break;
}
}
///// 走时程序 //////////
void timer(void) //time[3] 时0 秒1 分2 nian ri yue
{
if(time[1]==59)
{
time[1]=0;
if(time[2]==59)
{
time[2]=0;
if(time[0]==23)
{
time[0]=0;
if(date[1]==dpm())
{
date[1]=1;
if(date[2]==12)
{
date[2]=1;
date[0]=date[0]+1;
}
else
date[2]=date[2]+1;
}
else
date[1]=date[1]+1;
}
else
time[0]=time[0]+1;
}
else
time[2]=time[2]+1;
}
else
time[1]=time[1]+1;
}
/////// 延时 //////////
void delay(uint i) //延时ims
{
uint x,y;
for(x=i;x>0;x--)
for(y=124;y>0;y--)
;
}
///////// 判键 ////////////////
uint scan(void)
{
uint idata i=0;
PA8155=i;
i=PC8155&7;
//i=i&0x7;
if(i==0x7)
i=0xff;
else
i=f_key();
return i;
}
//////// 求键值 ////////////////
uint f_key(void)
{
uint idata i=1;
uint lx,rx;
delay(10); //去抖动
switch(PC8155&7)
{
case 3: rx=3;break;
case 5: rx=2;break;
case 6: rx=1;break;
}
while(1)
{
PA8155=i;
lx=PC8155&7;
if(lx==7)
break;
i=i<<1;
}
switch(i)
{
case 8: lx=3;break;
case 4: lx=2;break;
case 2: lx=1;break;
case 1: lx=0;break;
}
i=rx+lx*3;
if(i==11)
i=0;
while(1)
{
display();
lx=PC8155&7;
if(lx==7)
break;
}
return i;
}
////////// 显示 //////////////
void display(void)
{
uint j,n,k=0;
uint i=0x20;
for(n=0;n<6;n++)
{
PA8155=i;
j=st[dis[k]];
if(k==0)
if(O_DOT==1)
if(DOT==1)
j=j^0x80;
PB8155=j;
delay(1);
PB8155=0xff;
i=i>>1;
k=k+1;
}
}
////// 分解传送 /////////
void dvid(uint *p)
{
uint k;
for(k=0;k<6;k=k+2)
{
dis[k]=*p%10;
dis[k+1]=*p/10;
p=p+1;
}
}
//// 闰年判断 /////////
void leap_y(void)
{
if(date[0]%4==0)
leap=1;
else
leap='0';
}
//// 每月天判断/////////
uint dpm(void)
{
uint i;
leap_y();
switch(date[2])
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
i=31;break;
case 2:
if(leap==1)
i=29;
else
i=28;
break;
default:
i=30;break;
}
return i;
}
//// 修改函数/////////
void fun(uint set)
{
uint i;
switch(set)
{
case 0: // 时间
time[1]=0;
time_m();
break;
case 1: // 日期
O_DOT='0';
data_m();
O_DOT=1;
break;
case 3: // 闹钟
O_DOT='0';
while(1)
{
dvid(exch);
display();
i=scan();
if(i==10)
{
alarm1=!alarm1;
break;
}
}
if(alarm1==1)
alarm[1]=161;
else
alarm[1]=160;
while(1)
{
dvid(exch);
display();
i=scan();
if(i==12)
{
time_m();
break;
}
}
O_DOT=1;
break;
case 2: // 秒表
while(1)
{
dvid(exch);
display();
i=scan();
if(i==10)
TR1=1;
if(i==12)
TR1='0';
if(TR1=='0')
if(i==0)
{
stop_w[0]=stop_w[1]=stop_w[2]=0;
break;
}
}
break;
}
}
void time_m(void)
{
uint i;
O_DOT='0';
if(set==0)
dis[2]=dis[3]=0; //秒清零
dis[1]=0;
while(1)
{
display();
i=scan();
if(i<3)
dis[1]=i;
if(i==12)
break;
} // 时高位修改
dis[0]=0;
while(1)
{
display();
i=scan();
if(dis[1]==2)
{
if(i<4)
dis[0]=i;
else
if(i==12)
break;
}
else
if(i==12)
break;
else
if(i<10)
dis[0]=i;
} // 时低位修改
if(set==0)
time[0]=dis[1]*10+dis[0];
else
alarm[0]=dis[1]*10+dis[0];
dis[5]=0;
while(1)
{
display();
i=scan();
if(i<6)
dis[5]=i;
if(i==12)
break;
} // 分高位修改
dis[4]=0;
while(1)
{
display();
i=scan();
if(i==12)
break;
else
if(i<10)
dis[4]=i;
} //分低位修改
if(set==0)
{
time[2]=dis[5]*10+dis[4];
time[1]=0; //秒位清零
}
else
alarm[2]=dis[5]*10+dis[4];
O_DOT=1;
}
////////// 日期修改子函数 ///////////
void data_m(void)
{
uint i;
dis[1]=0;
while(1)
{
display();
i=scan();
if(i<10)
dis[1]=i;
if(i==12)
break;
} // 年高位修改
dis[0]=0;
while(1)
{
display();
i=scan();
if(i<10)
dis[0]=i;
if(i==12)
break;
} // 年低位修改
date[0]=dis[1]*10+dis[0];
dis[5]=0;
while(1)
{
display();
i=scan();
if(i<2)
dis[5]=i;
if(i==12)
break;
} // 月高位修改
dis[4]=0;
while(1)
{
display();
i=scan();
if(dis[5]==0)
{
if(i<10)
dis[4]=i;
if(i==12)
break;
}
else
{
if(i<3)
dis[4]=i;
if(i==12)
break;
}
} //月低位修改
date[2]=dis[5]*10+dis[4];
dis[3]=0;
while(1)
{
display();
i=scan();
if(date[2]==2) // 2月
{
if(i<3)
dis[3]=i;
if(i==12)
break;
}
else
{
if(i<4)
dis[3]=i;
if(i==12)
break;
}
} // 日高位修改
dis[2]=0;
while(1)
{
i=dpm();
display();
i=scan();
if(i==12)
break;
else
if((dis[3]*10+i)<=dpm())
dis[2]=i;
} // 日低位修改
date[1]=dis[3]*10+dis[2];
}
////////// 闹钟 /////////////
void arm_c()
{
if(alarm[1]==161)
{
if(time[0]==alarm[0]&&time[2]==alarm[2])
{
buzzer='0';
if(scan()!=0xff)
alarm[1]=160;
}
}
else
buzzer=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -