📄 at89c2051clock.c
字号:
#include<atmel/reg2051.H>
#define dispseg P1
sbit bsel3=P3^0;
sbit bsel2=P3^1;
sbit bsel1=P3^2;
sbit bsel0=P3^3;
sbit setkey=P3^7;
sbit inckey=P3^4;
sbit deckey=P3^5;
volatile bit sflag=0;
typedef unsigned char uchar;
typedef unsigned int uint;
uchar psec,sec,minu,hour,day,month,keyin,keyinflag=0,wei,mod=0,video[4],iicnt=0;
uchar mpsec=0,msec=0,tempmpsec=0,tempmsec=0;
uchar lianpsec=0,lianflag=0;
uchar code segcode[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uint twinkle;
volatile bit twiflag,mflag=0,tempflag=0,lian=0;//twiiflag;
//**********************************************************************
//中断服务程序T0
void t0int (void) interrupt 1 using 1
{ static uchar icnt=0;
if((++icnt)>=20)
{
icnt=0;
if(mflag==1) //跑表信号如果为1,则跑表启动
{if((++mpsec)>=100) //跑表1/100秒计
{ mpsec=0;
if((++msec)>=100) //跑表秒计
msec=0;
}
}
if((++psec)>=100) //时间计算
{ psec=0;
if((++sec)>=60)
{ sec=0;
if((++minu)>=60)
{
minu=0;
if((++hour)>=24)
{ hour=0;
switch(month)
{ case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(day==31)
{day=1;if(month==12)month=1;else month++;}
else
day++;
break;
case 4:case 6:case 9:case 11:
if(day==30)
{day=1;month++;}
else
day++;
break;
case 2:
if(day==28){day=1;month=3;}
else day++;
break;
}}
}
}
}
if((!((++lianpsec)%keyinflag))&&lian) //按键连加
{ switch(mod)
{ case 1:
if(keyin==0xA0)
{if(minu==59)
minu=0;
else
minu++;}
if(keyin==0x90)
{if(minu==0)
minu=59;
else
minu--; }
break;
case 2: if(keyin==0x90)
{if(hour==0)
hour=23;
else
hour--;}
if(keyin==0xa0){if(hour==23)
hour=0;
else
hour++;}
break;
case 5: if(keyin==0x90)
{if(month==12)
month=1;
else
month++;}
if(keyin==0xa0) switch(month)
{ case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(day==31)
day=1;
else
day++;
break;
case 4:case 6:case 9:case 11:
if(day==30)
day=1;
else
day++;
break;
case 2:
if(day==28)day=1;
else day++;
break;
}
break;
}
}
}
}
//************************************************************************
//中断服务程序T1
//LED显示扫描
void t1int (void) interrupt 3 using 2
{
if((++iicnt)==10)
{
iicnt=0;
bsel0=1;
bsel1=1;
bsel2=1;
bsel3=1;
if((++twinkle)>=50) //闪烁信号
{
twinkle=0;
twiflag=~twiflag;
}
if(wei>=3)wei=0; else wei++;
//扫描位移动
//模式选择
switch(mod)
{ case 0:
case 1:
case 2: //0 1 2显示分秒
{ video[0]=minu%10;
video[1]=minu/10;
video[2]=hour%10;
video[3]=hour/10;
if(wei!=2||twiflag==0)
dispseg=segcode[video[wei]];
else
dispseg=segcode[video[2]]&0x7F;
//if(twiflag==0&&(mod==1&&(wei==0||wei==1)||mod==2&&(wei==2||wei==3)))
// { dispseg=0xff; }//twiiflag=1;}
// else
// {twiiflag=0;}
} break;
case 3: //显示跑表
{ if(tempflag)
{ video[0]=tempmpsec%10; //显示暂停数据
video[1]=tempmpsec/10;
video[2]=tempmsec%10;
video[3]=tempmsec/10;
}
else
{ video[0]=mpsec%10; //显示跑表数据
video[1]=mpsec/10;
video[2]=msec%10;
video[3]=msec/10;
}
dispseg=segcode[video[wei]]; //跑表运行时有四位小数点闪动
if(mflag==1&&twiflag==1)
dispseg=dispseg&0x7f;
//dispseg=0xff;
} break;
case 4: { video[0]=sec%10; //显示秒
video[1]=sec/10;
video[2]=0;
video[3]=0;
dispseg=segcode[video[wei]];
if(wei>1)dispseg=dispseg&0x7f;
} break;
case 5: //显示日月
{ video[0]=day%10;
video[1]=day/10;
video[2]=month%10;
video[3]=month/10;
dispseg=segcode[video[wei]];
if(wei<=1)dispseg=dispseg&0x7f;
}break;
}
if((!(twiflag==0&&(mod==1&&(wei==0||wei==1)||mod==2&&(wei==2||wei==3))))||lian) //判断时间修改时的闪动
switch(wei)
{case 0:bsel0=0;break; //显示相应的位
case 1:bsel1=0;break;
case 2:bsel2=0;break;
case 3:bsel3=0;break;
}
}
}
//**************************************************************
//初始化程序
void timerinit(void)
{
TMOD=0x22; //都用自动重装载模式
TH0=TL0=256-250;
TH1=TL1=256-251;
IP=0x02;
IE=0x8A;
TR0=TR1=1;
psec=0;sec=0;minu=0;hour=0;
}
//***********************************************
//键盘处理子程序
void keyinprocess(void) //选择模式
{
switch(mod)
{
case 0:
switch(keyin)
{
case 0x30:mod=1;break;
case 0x90:mod=5;break;
case 0xa0:mod=4;break;
}
break;
case 1:
switch(keyin)
{
case 0x30: mod=2;break;
case 0x90: if(minu==0)
minu=59;
else
minu--;
break;
case 0xa0: if(minu==59)
minu=0;
else
minu++;
break;
}
break;
case 2:
switch(keyin)
{
case 0x30: mod=3;break;
case 0x90: if(hour==0)
hour=23;
else
hour--;
break;
case 0xa0: if(hour==23)
hour=0;
else
hour++;
break;
}
break;
case 3:
switch(keyin)
{
case 0x30: mod=0;break;
case 0x90: if(mflag==0) //如果跑表停止
{if(tempflag==1) //如果此时为暂停显示
tempflag=0; //则改为跑表终止显示
else
{tempmpsec=mpsec=tempmsec=msec=0;} //非暂停显示则跑表清零
}
else
{tempmpsec=mpsec;tempmsec=msec;tempflag=!tempflag;} //如果跑表运行则显示暂停数据再按则继续
break;
case 0xa0: mflag=!mflag; //跑表停止运行切换
break;
}
break;
case 4: switch(keyin)
{
case 0x30:mod=0;break;
case 0x90:sec=0;break;
case 0xa0:mod=0;break;
}
break;
case 5: switch(keyin)
{
case 0x30:mod=0;break;
case 0x90: switch(month)
{ case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(day==31)
day=1;
else
day++;
break;
case 4:case 6:case 9:case 11:
if(day==30)
day=1;
else
day++;
break;
case 2:
if(day==28)day=1;
else day++;
break;
}break;
case 0xa0: if(month==12)
month=1;
else
month++;
break;
}
break;
}
}
void main(void)
{
volatile bit keyupflag=1;
uchar k, i, j;
timerinit();
while(1)
{
keyin=P3&0xb0; //读键盘
if(keyin!=0xb0) //判断有无键盘输入
{
if(keyinflag&&keyupflag) //当第一次确认有键按下
{
keyupflag=0;
keyinprocess();
}
else
{
if(keyinflag==0)keyinflag=64;
if((k<2)&&keyinflag>8){keyinflag/=2;k=80;lian=1;}//一旦有连键按下则0.4秒加倍
else k--;
}
}
else
{
keyinflag=0;
keyupflag=1;
lian=0;
k=200;
}
for(i=18;i>=1;i--)
for(j=50;j>=1;j--); //延时
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -