51单片机万年历
功能:
24小时计时、年月日,按键控制时间的调整、闹钟
代码片
代码片
.
/*****************
具体测试接线如下:
P3口接7个按键、
P0口接数码管段选
P2口为数码管位选
*****************/
#include<reg51.h>
//#include<stdio.h>
unsigned char m=1,f=0,s=0,n=0,flag=0;//时钟的秒分小时
unsigned char dm=0,df=0,ds=0;//闹钟的时分秒
unsigned char n_1=20;n_2=22,y=2,r=22,nian=0;//年月日
unsigned char leap_Year=0,common_Year=0;//测试
//#define leap_Year
//#define common_Year
//sbit l1=P2^0;//位选个位
//sbit l2=P2^1;//位选十位
sbit k1=P3^0;//分加
sbit k2=P3^1;//分减
sbit k3=P3^2;//时加
sbit k4=P3^3;//时减
sbit k5=P3^4;//清零
sbit k6=P3^5;//闹钟定时,按下进入设置状态
sbit k7=P3^6;//年月日,按下显示
sbit led=P1^0;//蜂鸣器以LED灯代替
unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴断码表
/***********延时函数************/
void delay(unsigned int t)
{
unsigned i,j;
for(i=0;i<t;i++)
{for(j=0;j<200;j++);}
}
/***********主函数**************/
void main()
{
//TMOD=0x11;//定时器0、1工作方式1
TMOD=0x01;//定时器0工作方式1
TH0=(65536-50000)/256;//赋初值50ms
TL0=(65536-50000)%256;
//TH1=(65536-50000)/256;
//TL1=(65536-50000)%256;
EA=1;//打开总中断
ET0=1;
TR0=1;
//ET1=1;
//TR1=1;
//YearCOL();
//testFuntion();
while(1){
nian=n_1*100+n_2;//计算年份
/**************************闰年判断,否则为平年*************************/
// if((nian%400==0)||((nian%100!=0)&&(nian%4==0)))
// leap_Year=29;//闰年,此处只做测试
// else
// common_Year=28;//平年,******
/********************年月日显示状态**************************/
if(k7==0){
P2=0xbf;P0=tab[r/10];delay(2);
P2=0x7f;P0=tab[r%10];delay(2);
P2=0xdf;P0=tab[y%10];delay(2);
P2=0xef;P0=tab[y/10];delay(2);
P2=0xf7;P0=tab[n_2%10];delay(2);
P2=0xfb;P0=tab[n_2/10];delay(2);
P2=0xfd;P0=tab[n_1%10];delay(2);
P2=0xfe;P0=tab[n_1/10];delay(2);
if(k1==0){
delay(100);
r=r+1;//日加一
if((nian%400==0)||((nian%100!=0)&&(nian%4==0))){//优先判断年份是否为闰年
if((r==30)&&(y==2)){r=1;}}//闰年2月29天,写30的原因是当时间为30时会立刻消除,以下同理
else if((y==2)&&(r==29)){r=1;}//else{//平年2月28天,时间上没有0天,故初始化为1,以下同理
if((y==1||y==3)||(y==5||y==7)||(y==8||y==10)||(y==12)){//判断月份,1、3、5、78、10、12有31天
if(r==32){r=1;}}
else if((y==4||y==6)||(y==9||y==11)){if(r==31){r=1;}}//4、6、9、11月为30天
delay(50);
}
if(k2==0){
delay(100);
y=y+1;//月加一
if(y==13){y=1;}
delay(50);
}
if(k3==0){
delay(100);
n_2=n_2+1;//年加一,无年减一
if(n_2==100){n_2=0;}
delay(50);
}
if(k4==0){
delay(100);
n_1=n_1+1;//年份加百
if(n_1==100){n_1=0;}
delay(50);
}
if(k5==0){
delay(100);
if(n_1==0){n_1=100;}
n_1=n_1-1;//年份减百
delay(50);
}
}
else{
/**********k6按键按下则进入闹钟定时状态
此状态内,可以任意调整需要定时的时间。**************/
if(k6==0){
if(k1==0){
delay(100);
df=df+1;//分钟加一
if(s==60){s=0;}
delay(50);
}
if(k2==0){
delay(100);
if(s==0){s=60;}
df=df-1;//分钟减一
delay(50);
}
if(k3==0){
delay(100);
ds=ds+1;//小时加一
if(ds==24){ds=0;}
delay(50);
}
if(k4==0){
delay(100);
if(ds==0){ds=24;}
ds=ds-1;//小时减一
delay(50);
}
if(k5==0){
m=0;f=0;s=0;//清零,意外调错时间可用
}
/*******************闹钟时间调整实时显示***************/
P2=0xbf;P0=tab[dm/10];delay(2);
P2=0x7f;P0=tab[dm%10];delay(2);
P2=0xdf;P0=0x80;delay(2);
P2=0xef;P0=tab[df%10];delay(2);
P2=0xf7;P0=tab[df/10];delay(2);
P2=0xfb;P0=0x80;delay(2);
P2=0xfd;P0=tab[ds%10];delay(2);
P2=0xfe;P0=tab[ds/10];delay(2);
//if((df||ds)&&ds==s)
}
/***********非闹钟设置状态************/
else{
/********判断数字时钟所走的时间是否等于闹钟定时时间***************/
if((df||ds)&&(df==f)&&(ds==s))led=0;
else led=1;//蜂鸣器鸣响一分钟
if(k1==0){
delay(100);
f=f+1; //分钟加一
if(f==60){f=0;}
delay(50);
}
if(k2==0){
delay(100);
if(f==0){f=60;}
f--; //分钟减一
delay(50);
}
if(k3==0){
delay(100);
s=s+1; //小时加一
if(s==24){s=0;}
delay(50);
}
if(k4==0){
delay(100);
if(s==0){s=24;}
s--; //小时减一
delay(50);
}
if(k5==0){
m=0;f=0;s=0;//清零
}
/***************数码管显示时间******************/
P2=0xbf;P0=tab[m/10];delay(2);
P2=0x7f;P0=tab[m%10];delay(2);
P2=0xdf;P0=0x80;delay(2);
P2=0xef;P0=tab[f%10];delay(2);
P2=0xf7;P0=tab[f/10];delay(2);
P2=0xfb;P0=0x80;delay(2);
P2=0xfd;P0=tab[s%10];delay(2);
P2=0xfe;P0=tab[s/10];delay(2);
}
}
}
}
/****************初始化定时器,并进行时间加计数,每隔一秒加一*************/
void timer_0(void) interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
flag++;
if(flag==20)
{
flag=0;m++;if(m==60){
m=0;f++;if(f==60){
f=0;s++;if(s==24){
s=0;r++;
if((y==1||y==3)||(y==5||y==7)||(y==8||y==10)||(y==12)){
if(r==32){
r=1;y++;
if(y==13){
y=1;n_2++;if(n_2==100){
n_2=0;n_1++;if(n_1==99){//八位数码管最高显示9999年,到达极限关闭计时器
n_2=99;TR0=0;
}
}
}
}
}
else{
if((y==4||y==6)||(y==9||y==11)){
if(r==31){
r=1;y++;if(y==13){
y=1;n_2++;if(n_2==100){
n_2=0;n_1++;if(n_1==99){
n_2=99;TR0=0;
}
}
}
}
}
else{
if((y==2)&&((nian%400==0)||((nian%100!=0)&&(nian%4==0)))){
if(r==30){
r=1;y++;if(y==13){
y=1;n_2++;if(n_2==100){
n_2=0;n_1++;if(n_1==99){
n_2=99;TR0=0;
}
}
}
}
}
else{
if((y==2)&&(r==29))r=1;y++;
if(y==13){
y=1;n_2++;if(n_2==100){
n_2=0;n_1++;if(n_1==99){
n_2=99;TR0=0;
}
}
}
}
// if(y==13){
// y=1;n_2++;if(n_2==100){
// n_2=0;n_1++;if(n_1==99){
// n_2=99;TR0=0;
// }
// }
// }
}
}
}
}
}
}
}