51单片机数字万年历仿真
感冒了,头好疼啊,坚持两分钟程序做了详细的说明,不再赘述……
/***********************************************************************************************/
/********************************本系统选用atmel公司的AT89C51单片机,*************************/
/********************************所用软件为keil 9.1*******************************************/
/********************************仿真软件protes 7.1*******************************************/
#include
#define uchar unsigned char
#define uint unsigned int
#define DQ P3_7
uint sec=00; //系统初始时间2013.1.4.20:40:00
uint min=40;
uint hour=20;
uint day=4;
uint month=1;
uint yearl=13; //年份地位
uint yearh=20; //年份高位-不能调整
uint tcnt;
uint cursor=0; //循环变量,用于调整模式时计数,最大为7
uchar a=0xff;
uchar code Seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管 数字对应数组
void delay(uint t) //延时函数delay
{
uint i;
while(t--)
{for (i=0;i
}
void Tdelay(unsigned int i) //延时函数Tdelay
{
while(i--);
}
void Kdelay() //延时函数Kdelay,用于按键时消抖延时
{
uchar i,j;
for(i=200;i>0;i--)
for(j=248;j>0;j--);
}
//显示函数:用于对应数字送入数码管显示,对应为动态显示
void display(uchar L1,uchar L2,uchar L3,uchar L4,uchar L5,uchar L6,uchar L7,uchar L8,uchar L9,uchar L10,uchar L11,uchar L12,uchar L13,uchar L14,uchar L15,uchar L16)
{
P2=0x7F;P0=L1;delay(1); //yearh
P2=0xBF;P0=L2;delay(1); //yearh
if(cursor==6){P2=0xDF|a;P0=L3;delay(1);}else{P2=0xDF;P0=L3;delay(1);} //yearl
if(cursor==6){P2=0xEF|a;P0=L4;delay(1);}else{P2=0xEF;P0=L4;delay(1);} //yearl
if(cursor==5){P2=0xF7|a;P0=L5;delay(1);}else{P2=0xF7;P0=L5;delay(1);} //month
if(cursor==5){P2=0xFB|a;P0=L6;delay(1);}else{P2=0xFB;P0=L6;delay(1);} //month
if(cursor==4){P2=0xFD|a;P0=L7;delay(1);}else{P2=0xFD;P0=L7;delay(1);} //day
if(cursor==4){P2=0xFE|a;P0=L8;delay(1);}else{P2=0xFE;P0=L8;delay(1);} //day
P2=0xFF;
if(cursor==3){P1=0x7F|a;P0=L9;delay(1);}else{P1=0x7F;P0=L9;delay(1);} //hour
if(cursor==3){P1=0xBF|a;P0=L10;delay(1);}else{P1=0xBF;P0=L10;delay(1);} //hour
if(cursor==2){P1=0xDF|a;P0=L11;delay(1);}else{P1=0xDF;P0=L11;delay(1);} //min
if(cursor==2){P1=0xEF|a;P0=L12;delay(1);}else{P1=0xEF;P0=L12;delay(1);} //min
if(cursor==1){P1=0xF7|a;P0=L13;delay(1);}else{P1=0xF7;P0=L13;delay(1);} //sec
if(cursor==1){P1=0xFB|a;P0=L14;delay(1);}else{P1=0xFB;P0=L14;delay(1);} //sec
P1=0xFD;P0=L15;delay(1); //temp 缓存
P1=0xFE;P0=L16;delay(1); //temp
}
main()
{
uint i;
TMOD=0x02; //设置模式为定时器T0的模式2 (8位自动重装计数初值的计数值)
TH0=0x06; //设置计数器初值,靠TH0存储重装的计数值X0=256-250=6
TL0=0x06;
TR0=1; //启动T0
ET0=1; //开启定时器T0中断允许
EA=1; //开启中断总控制
while(1)
{
if(P3_0==0) //判断是否为“调整模式” p3_0==0:是。p3_0==1:不是
{
Kdelay(); //按键消抖,防止不确定干扰
if(P3_0==0) //再次判断是否为调整模式,若是执行以下操作
{
cursor++; //循环变量+1,对应于调整为换一个,如前面调整为秒的话,此时调整的是分
if(cursor>=7){cursor=0;} //若循环变量cursor>=7,则赋值为0,对应于确认(即年的高位)
}
}
if(P3_1==0) //若p3_1为低电平,对应于'+'模式
{
Kdelay(); //消抖
if(P3_1==0) //对应调整以下各位,如cursor==1时对应于sec秒加1
{
if(cursor==1){sec++;if(sec==60)sec=0;}
if(cursor==2){min++;if(min==60)min=0;}
if(cursor==3){hour++;if(hour==24)hour=0;}
if(cursor==4){day++;if(day==31)day=0;}
if(cursor==5){month++;if(month==12)month=0;}
if(cursor==6){yearl++;if(yearl==100)yearl=0;}
if(cursor==7){yearh++;if(yearh==30)yearh=20;}
}
}
if(P3_2==0) //p3_2为低电平对应为“-”模式,与上面类似
{
Kdelay();
if(P3_2==0)
{
if(cursor==1){sec--;}
if(cursor==2){min--;}
if(cursor==3){hour--;}
if(cursor==4){day--;}
if(cursor==5){month--;}
if(cursor==6){yearl--;}
if(cursor==7){yearh--;}
}
}
//显示万年历数据
display(Seg[yearh/10],Seg[yearh%10],Seg[yearl/10],Seg[yearl%10],Seg[month/10],Seg[month%10],Seg[day/10],Seg[day%10],Seg[hour/10],Seg[hour%10],Seg[min/10],Seg[min%10],Seg[sec/10],Seg[sec%10],Seg[i/100],Seg[i/10%10]);
}
}
void t0(void)interrupt 1 using 0 //t0的中断程序
{
tcnt++;
if(tcnt==4000)//定时器的定时计数,4000次250us为1秒
{
tcnt=0; //循环变量tcnt
P3_3=~P3_3;
a=~a;
sec++;
if(sec==60) //以下为万年历算法,不再说明,与实际相同
{
sec=0;
min++; //每60秒分+1,并清零秒
if(min==60)
{
min=0;
hour++; //没60分,时+1,并清零分钟
if(hour==24)
{
hour=0;
day++; //每24小时,日期+1,并清零时
// 以下为闰年判断
if(month==2&&((yearl==0&&yearh%4==0)||(yearl!=0&&yearl%4==0))&&day==30)day=1;
else if(month==2&&day==29)day=1;
else if((month==4||month==6||month==9||month==11)&&day==31)day=1;
else if(day==32)day=1;
if(day==1)
{
month++;
if(month==13)
{
month=1;
yearl++;
if(yearl==100)
{
yearl=0;
yearh++;
if(yearh==100)
{
yearh=20;
}
}
}
}
}
}
}
}
}
电路图:
结果忘了截图…
下次补上
成功
http://wenku.baidu.com/view/facf59c9da38376baf1faeb0.html