用单片机做个万年历

大概需要多长时间,需要准备些什么! 我用的是51和ds1320

如果你用液晶的话,加个1602,再加上4个按键就可以了。
如果你用数码管的话,还要买一片154.
最好加上蜂鸣器,和几个LED做指示灯

硬件很容易做出来,软件就麻烦点了,需要看一下1602的用法(用数码管就可略此步了)1302的用法。

之后,做电路板估计要厂家做,自己设计到厂家做好至少2周吧,硬件焊接加测试几天完活,软件设计很漫长,如果只用业余时间做,至少2周。

祝你成功
温馨提示:内容为网友见解,仅供参考
第1个回答  2009-04-22
#include<AT89X51.h>
unsigned char code dispcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};//共阴极
unsigned char dispbitcode[]={0x00,0x21,0x42,0x63,0x84,0xA5,0xC6,0xE7};//管子的选择
unsigned char dispbuf[8]={0,0,10,0,0,10,2,1}; //16为显示间断号符
unsigned char dispbym[8]={1,2,7,0,6,0,0,2};
unsigned char dispbitcnt;
unsigned char second;
unsigned char minite;
unsigned char hour;
unsigned char day;
unsigned char month;
unsigned char yearh;
unsigned char yearl;
unsigned int tcnt;
unsigned char mstcnt;
unsigned char i,j;
void main(void)
{
TMOD=0x02; //设置模式为定时器T0的模式2 (8位自动重装计数初值的计数值)
TH0=0x06; //设置计数器初值,靠TH0存储重装的计数值X0=256-250=6
TL0=0x06;
TR0=1; //启动T0
ET0=1; //开启定时器T0中断允许
EA=1; //开启中断总控制
yearh=20;
yearl=6;
month=7;
day=21;
hour=12; //初始值为12:00:00
while(1)
{
if(P0_0==0) //扫描秒钟按钮
{
for(i=5;i>0;i--) //按钮抖动消除
for(j=248;j>0;j--); //计时
if(P0_0==0)
{
second++;
if(second==60)
{
second=0;
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
while(P0_0==0);
}
}

if(P0_1==0) //扫描分钟按钮
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
}
}

if(P0_2==0) //扫描时钟按钮
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
}
}

if(P0_3==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_3==0)
{
day++;
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;
dispbym[0]=day%10;
dispbym[1]=day/10;
while(P0_3==0);
}
}

if(P0_4==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_4==0)
{
month++;
if(month==13)month=1;
dispbym[2]=month%10;
dispbym[3]=month/10;
while(P0_4==0);
}
}

if(P0_5==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_5==0)
{
yearl++;
if(yearl==100)
{
yearl=0;
yearh++;
if(yearh==100)yearh=20;
}
dispbym[4]=yearl%10;
dispbym[5]=yearl/10;
dispbym[6]=yearh%10;
dispbym[7]=yearh/10;
while(P0_5==0);
}
}

}
}

void t0(void)interrupt 1 using 0 //t0的中断程序
{
mstcnt++;
if(mstcnt==8) //8次250us为2ms,即每隔2ms扫描一个数码管
{
mstcnt=0;
P1=dispcode[dispbuf[dispbitcnt]];
P2=dispcode[dispbym[dispbitcnt]];
P3=0xff;
P3=dispbitcode[dispbitcnt]; //管子的选择
dispbitcnt++;
if(dispbitcnt==8)
{
dispbitcnt=0;
}
}
tcnt++;
if(tcnt==4000) //定时器的定时计数,4000次250us为1秒
{
tcnt=0;
second++;
if(second==60) //从秒到时层层嵌套,程序较为精练
{
second=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
day++;
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;
}
}
}
}
}
}
}
dispbuf[0]=second%10; //送显示数据
dispbuf[1]=second/10;

dispbuf[3]=minite%10;
dispbuf[4]=minite/10;

dispbuf[6]=hour%10;
dispbuf[7]=hour/10;

dispbym[0]=day%10;
dispbym[1]=day/10;

dispbym[2]=month%10;
dispbym[3]=month/10;

dispbym[4]=yearl%10;
dispbym[5]=yearl/10;

dispbym[6]=yearh%10;
dispbym[7]=yearh/10;
}
}
相似回答