#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
sbit key1=P3^0; //模式切换:0.时分秒显示,1.时分秒调整,2.年月日显示,3.年月日调整,4.闹钟显示,5.闹钟调整
sbit key2=P3^1;//调秒或日
sbit key3=P3^2;//调分或月
sbit key4=P3^3;//调时或年
sbit key5=P3^4;//24或12转换
sbit key6=P3^5;//关闭闹钟
sbit horn=P1^0;//蜂鸣器
sbit led1=P1^1;//时分秒显示,闪烁代表调整
sbit led2=P1^2;//年月日显示,闪烁代表调整
sbit led3=P1^3;//闹钟显示,闪烁代表调整
sbit led4=P1^4;//24制灭,12制亮
sbit led5=P1^5;//上午灭,下午亮
unsigned char sech=0,secl=0,minh=0,minl=0,hourh=0,hourl=0,mark=0,
sech1=0,secl1=0,minh1=0,minl1=0,hourh1=0,hourl1=0,mark1=0,
year4=0,year3=0,year2=0,year1=0,monh=0,monl=0,dayh=0,dayl=0,//定义时间闹钟日期存储
mark2=0,mark3=1;//2是进制标志,3是上下午标志
unsigned int num=0,sec=0,min=0,hour=0,hour2=0,//时间时分秒计数
num1=0,sec1=6,min1=6,hour1=6,hour3=0,//闹钟时分秒技计数
year=0,mon=1,day=1;//日期年月日计数
unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管1到10
void keyscan();//键盘扫描韩函数
void showtime();//时钟显示函数
void showyear();//年月日显示函数
void showtime1();//闹钟显示函数
void clock();//闹钟发声函数
void time0();//中断函数
void delay(unsigned char z)
{unsigned char x,y;
for(x=z;x>0;x--)
for(y=255;y>0;y--);}//延时函数
void time0() interrupt 1
{num++;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
if(num==20)//20次为1S
{num=0;
sec++;}
if(sec>=60)
{sec=0;
min++;}//60秒清零,分加一
if(min>=60)
{min=0;
hour++;}//60分清零,时加一,下面以此类推
if(hour>=12)
{mark3=0;}
if(hour>=24)
{mark3=1;
hour=0;
day++;}
if(mon==2)//判断是否为2月
{if(year%4==0)//判断是否为闰年
{if(day>=30)
{day=1;mon++;}}
else if(day>=29)
{day=1;mon++;}}
if((mon==1)||(mon==3)||(mon==5)||(mon==7)||(mon==8)||(mon==10)||(mon==12))//判断是否是大月
{if(day>=32)
{day=1;mon++;}}
if((mon==4)||(mon==6)||(mon==9)||(mon==11))//判断是否是小月
{if(day>=31)
{day=1;mon++;}}
if(mon>=13)
{mon=1;year++;}
if(year>=31)
{year=0;}
}//中断函数T0,1S,累加时分秒,年月日
void showtime()
{
secl=sec%10;//秒的个位
sech=sec/10;//秒的十位,下面类推
minl=min%10;
minh=min/10;
hourl=hour2%10;
hourh=hour2/10;
P2=0xfe;//循环输出数码管显示码
P0=table[secl];
delay(5);
P2=0xfd;
P0=table[sech];
delay(5);
P2=0xfb;
P0=0x40;
delay(5);
P2=0xf7;
P0=table[minl];
delay(5);
P2=0xef;
P0=table[minh];
delay(5);
P2=0xdf;
P0=0x40;
delay(5);
P2=0xbf;
P0=table[hourl];
delay(5);
P2=0x7f;
P0=table[hourh];
delay(5);
}//时钟显示函数
void showtime1()
{
secl1=sec1%10;//原理同上
sech1=sec1/10;
minl1=min1%10;
minh1=min1/10;
hourl1=hour3%10;
hourh1=hour3/10;
P2=0xfe;
P0=table[secl1];
delay(5);
P2=0xfd;
P0=table[sech1];
delay(5);
P2=0xfb;
P0=0x40;
delay(5);
P2=0xf7;
P0=table[minl1];
delay(5);
P2=0xef;
P0=table[minh1];
delay(5);
P2=0xdf;
P0=0x40;
delay(5);
P2=0xbf;
P0=table[hourl1];
delay(5);
P2=0x7f;
P0=table[hourh1];
delay(5);
}//闹钟显示函数
void showyear()
{
dayl=day%10;//原理同上
dayh=day/10;
monl=mon%10;
monh=mon/10;
year4=year%10;
year3=year/10;
year2=0;
year1=2;
P2=0xfe;
P0=table[dayl];
delay(5);
P2=0xfd;
P0=table[dayh];
delay(5);
P2=0xfb;
P0=table[monl];
delay(5);
P2=0xf7;
P0=table[monh];
delay(5);
P2=0xef;
P0=table[year4];
delay(5);
P2=0xdf;
P0=table[year3];
delay(5);
P2=0xbf;
P0=table[year2];
delay(5);
P2=0x7f;
P0=table[year1];
delay(5);
}//年份显示函数
void keyscan()
{
if(key5==0)//进制切换按键按下
{delay(10);//消抖
if(key5==0)//再次判断进制按键按下
{mark2++;//进制标志加1
if(mark2>=2)
mark2=0;}//标志清零
while(key5==0);//松开按键跳出
}
if(key1==0) //模式切换按键按下
{ delay(10);//消抖,下同
if(key1==0)//再次判断按键是否按下
{mark++;
if(mark>=6)
mark=0;} //按键按下次数标志加1,6次清零
while(key1==0);} //松开按键跳出
if(mark==1)//时间调整
{if(key2==0)//调秒键按下
{delay(10);
if(key2==0)//再次判断键是否按下
{sec++;//秒加1
if(sec>=60)//判断秒是否到60S
sec=0;}//到60S清零
while(key2==0);//释放键
}
if(key3==0)//调分,原理同上
{delay(10);
if(key3==0)
{min++;
if(min>=60)
min=0;}
while(key3==0);
}
if(key4==0)//调时,原理同上
{delay(10);
if(key4==0)
{hour++;
if(hour==24)
hour=0;}
while(key4==0);
}
}
if(mark==5)//闹钟调整,原理同上
{if(key2==0)
{delay(10);
if(key2==0)
{sec1++;
if(sec1>=60)
sec1=0;}
while(key2==0);
}
if(key3==0)
{delay(10);
if(key3==0)
{min1++;
if(min1>=60)
min1=0;}
while(key3==0);
}
if(key4==0)
{delay(10);
if(key4==0)
{hour1++;
if(hour1>=24)
hour1=0;}
while(key4==0);
}
}
if(mark==3)//年份调整,原理同上
{if(key2==0)
{delay(10);
if(key2==0)
{day++;
if(mon==2)
{if(year%4==0)
{if(day>=30)
day=1;}
else if(day>=29)
{ day=1;}
}
if((mon==1)||(mon==3)||(mon==5)||(mon==7)||(mon==8)||(mon==10)||(mon==12))
{if(day>=32)
day=1;}
if((mon==4)||(mon==6)||(mon==9)||(mon==11))
{if(day>=31)
day=1;}
}
while(key2==0);
}
if(key3==0)
{delay(10);
if(key3==0)
{mon++;
if(mon>=13)
mon=1;}
while(key3==0);
}
if(key4==0)
{delay(10);
if(key4==0)
{year++;
if(year>=31)
year=0;}
while(key4==0);
}
}
}//键盘扫描函数
void clock()
{ unsigned int i;
for(i=1000;i>0;i--)
{horn=1;
P1=0xfe;
delay(10);
horn=0;
P1=0xff;
delay(10);
if(key6==0)
{mark1=0;break;}
}
}//蜂鸣器发声函数
void to12()
{
if(mark2==1)
{led4=0;
if(hour>=12)
{hour2=hour-12;}
else {hour2=hour;}
if(hour1>=12)
{hour3=hour1-12;}
else {hour3=hour1;}
}
if(mark2==0)
{led4=1;
hour2=hour;
hour3=hour1;
}
}//24或12制转换函数
main()
{TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;ET0=1;TR0=1;//中断T0初始化
while(1)
{
keyscan();to12();
if(mark==0) {showtime();led1=0;}//显示时间,灯1常亮
if(mark==1) {showtime();led1=0;delay(50);led1=1;}//调整时间,灯1闪烁
if(mark==2) {showyear();led2=0;}//显示日期,灯2常亮
if(mark==3) {showyear();led2=0;delay(50);led2=1;}//调整日期,灯2闪烁
if(mark==4) {showtime1();led3=0;}//显示闹钟,灯3常量
if(mark==5) {showtime1();led3=0;delay(50);led3=1;}//调整闹钟,灯3闪烁
if((hour==hour1)&&(min==min1)&&(sec==sec1)){mark1=1;}//判断当前时间与闹钟是否一致
if(mark1==1){clock();}//闹钟响
led5=mark3;//关闭闹钟
}
}
全部资料51hei下载地址:
电子时钟程序+仿真.7z
(1.72 MB, 下载次数: 168)
|