51单片机实现万年历程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机实现万年历程序
51单片机实现万年历
利用AT89S52单片机的P0口来和另外几个口来控制1602液晶的显示和P1口还有其它口来控制ds12887时钟芯片。

设置四个按键,1个定义为时间设置功能键,一个定义为闹钟设置功能键,另外两个用来调节时间的增减。

原理图:
pcb图:
源程序:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit beep=P2^0;//蜂鸣器控制口
sbit timeadd=P2^1;//调节时间加
sbit timesub=P2^2;//调节时间减
sbit timeclk=P2^3;//闹钟设定键
sbit timefun=P2^4;//时间设定键
sbit lcdrs=P2^5;//液晶的命令和数据控制口
sbit ledrw=P2^6;//液晶的写数据口
sbit lcden=P2^7;//液晶显示模块的使能端
sbit timeds=P3^3;//时钟芯片地址闸
sbit timerw=P3^4;//时钟芯片读写
sbit timeas=P3^5;//时钟芯片地址闸
sbit timeen=P3^6;//时钟芯片片选
uchar code table[]="20 - - week ";
uchar code table1[]=" : : ";//要显示的字符串
char num,shi,fen,miao,nian=2000,yue,ri,week,numfun,anumfun,flag,flag1; uchar leap;
write_com(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_zhou(uchar add,uchar date) {
write_com(0x80+add);
write_date(0x30+date);
}
void write_ds(uchar add,uchar date){ timeen=0;
timeas=1;
timeds=1;
timerw=1;
P1=add;
timeas=0;
timerw=0;
P1=date;
timerw=1;
timeas=1;
timeen=1;
}
uchar read_ds(uchar add){
uchar ds_date;
timeas=1;
timeds=1;
timerw=1;
timeen=0;
P1=add;
timeas=0;
timeds=0;
P1=0xff;
ds_date=P1;
timeds=1;
timeas=1;
timeen=1;
return ds_date;
}
void keyscan(){
if(flag1==1)//用来关闭闹钟铃声
{
if(timeadd==0)
{
delay(5);
if(timeadd==0)
{
while(!timeadd==0);
flag1=0;
}
}
if(timesub==0)
{
delay(5);
if(timesub==0)
{
while(!timesub==0);
flag1=0;
}
}
}
if(timefun==0)
{
delay(5);
if(timefun==0)
{
while(!timefun);
flag=1;
numfun++;
if(numfun==1)
{
write_com(0x80+0x40+0x0a);
write_com(0x0f);
}
if(numfun==2)
{
write_com(0x80+0x40+0x07);
write_com(0x0f);
}
if(numfun==3)
{
write_com(0x80+0x40+0x04);
write_com(0x0f);
}
if(numfun==4)
{
write_com(0x80+0x0f);
write_com(0x0f);
}
if(numfun==5)
{
write_com(0x80+0x09);
write_com(0x0f);
}
if(numfun==6)
{
write_com(0x80+0x06);
write_com(0x0f);
}
if(numfun==7)
{
write_com(0x80+0x03);
write_com(0x0f);
}
if(numfun==8)
{
numfun=0;
flag=0;
}
}
}
if(numfun!=0)
{
if(timeadd==0)
{
delay(5);
while(!timeadd);
if(numfun==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(9,miao);
write_com(0x80+0x40+9);
write_ds(0,miao);
}
if(numfun==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(6,fen);
write_com(0x80+0x40+6);
write_ds(2,fen);
}
if(numfun==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(3,shi);
write_com(0x80+0x40+3);
write_ds(4,shi);
}
if(numfun==4)
{
week++;
if(week==8)
week=1;
write_zhou(0x0f,week);
write_com(0x80+0x0f);
write_ds(6,week);
}
if(numfun==5)
{
if(nian==0)
{
switch(yue){
case 1:ri++;if(ri==32) ri=1;break;
case 2:ri++;if(ri==30) ri=1;break;
case 3:ri++;if(ri==32) ri=1;break;
case 4:ri++;if(ri==31) ri=1;break;
case 5:ri++;if(ri==32) ri=1;break;
case 6:ri++;if(ri==31) ri=1;break;
case 7:ri++;if(ri==32) ri=1;break;
case 8:ri++;if(ri==32) ri=1;break;
case 9:ri++;if(ri==31)
ri=1;break;
case 10:ri++;if(ri==32)
ri=1;break;
case 11:ri++;if(ri==31)
ri=1;break;
case 12:ri++;if(ri==32)
ri=1;break;
}
}
else if(leap&&yue==2)
{
ri++;
if(ri==30)
ri=1;
}
else if(yue==2&&leap==0)
{
ri++;
if(ri==29)
ri=1;
}
else
switch(yue){
case 1:ri++;if(ri==32) ri=1;break;
case 3:ri++;if(ri==32) ri=1;break;
case 4:ri++;if(ri==31) ri=1;break;
case 5:ri++;if(ri==32) ri=1;break;
case 6:ri++;if(ri==31) ri=1;break;
case 7:ri++;if(ri==32) ri=1;break;
case 8:ri++;if(ri==32) ri=1;break;
case 9:ri++;if(ri==31) ri=1;break;
case 10:ri++;if(ri==32) ri=1;break;
case 11:ri++;if(ri==31) ri=1;break;
case 12:ri++;if(ri==32) ri=1;break;
}
write_nyr(8,ri);
write_com(0x80+0x08);
write_ds(7,ri);
}
if(numfun==6)
{
yue++;
if(yue==13)
yue=0;
write_nyr(5,yue);
write_com(0x80+0x05);
write_ds(8,yue);
}
if(numfun==7)
{
nian++;
if(nian==100)
nian=0;
leap=nian%4==0&&nian%100!=0;
write_nyr(2,nian);
write_com(0x80+2);
write_ds(9,nian);
}
}
if(timesub==0)
{
delay(5);
while(!timesub);
if(numfun==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(9,miao);
write_com(0x80+0x40+9);
write_ds(0,miao);
}
if(numfun==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(6,fen);
write_com(0x80+0x40+6);
write_ds(2,fen);
}
if(numfun==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(3,shi);
write_com(0x80+0x40+3);
write_ds(4,shi);
}
if(numfun==4)
{
week--;
if(week==0)
week=7;
write_zhou(0x0f,week);
write_com(0x80+0x0f);
write_ds(6,week);
}
if(numfun==5)
{
if(nian==0)
{
switch(yue){
case 1:ri--;if(ri==0) ri=31;break;
case 2:ri--;if(ri==0) ri=29;break;
case 3:ri--;if(ri==0) ri=31;break;
case 4:ri--;if(ri==0) ri=30;break;
case 5:ri--;if(ri==0) ri=31;break;
case 6:ri--;if(ri==0) ri=30;break;
case 7:ri--;if(ri==0) ri=31;break;
case 8:ri--;if(ri==0) ri=31;break;
case 9:ri--;if(ri==0) ri=30;break;
case 10:ri--;if(ri==0) ri=31;break;
case 11:ri--;if(ri==0) ri=30;break;
case 12:ri--;if(ri==0) ri=31;break;
}
}
else if(leap&&yue==2)
{
ri--;
if(ri==0)
ri=29;
}
else if(yue==2&&leap==0)
{
ri--;
if(ri==0)
ri=28;
}
else
switch(yue){
case 1:ri--;if(ri==0) ri=31;break;
case 3:ri--;if(ri==0) ri=31;break;
case 4:ri--;if(ri==0) ri=30;break;
case 5:ri--;if(ri==0) ri=31;break;
case 6:ri--;if(ri==0) ri=30;break;
case 7:ri--;if(ri==0) ri=31;break;
case 8:ri--;if(ri==0) ri=31;break;
case 9:ri--;if(ri==0) ri=30;break;
case 10:ri--;if(ri==0) ri=31;break;
case 11:ri--;if(ri==0) ri=30;break;
case 12:ri--;if(ri==0) ri=31;break;
}
write_nyr(8,ri);
write_com(0x80+0x08);
write_ds(7,ri);
}
if(numfun==6)
{
yue--;
if(yue==-1)
yue=12;
write_nyr(5,yue);
write_com(0x80+0x05);
write_ds(8,yue);
}
if(numfun==7)
{
nian--;
if(nian==-1)
nian=99;
leap=nian%4==0&&nian%100!=0;
write_nyr(2,nian);
write_com(0x80+2);
write_ds(9,nian);
}
}
}
}
void set_alarm(){
uchar ashi,afen,amiao;
if(timeclk==0)//判断是否按下闹钟设定键
{
delay(5);//延时消抖
if(timeclk==0)
{
while(!timeclk);
anumfun++;//按键次数加1
if(anumfun==1)
{
flag=1;
write_com(0x80+0x40+0x0a);
write_com(0x0f);
}
if(anumfun==2)
{
flag=1;
write_com(0x80+0x40+0x07);
write_com(0x0f);
}
if(anumfun==3)
{
flag=1;
write_com(0x80+0x40+0x04);
write_com(0x0f);
}
if(anumfun==4)
{
flag=0;
anumfun=0;
}
}
}
if(anumfun!=0)
{
if(timeadd==0)//如果加功能键按下
{
delay(5);
while(!timeadd);
if(anumfun==1) //设定秒
{
amiao++;
if(amiao==60)
amiao=0;
write_sfm(9,amiao);
write_com(0x80+0x40+9);
write_ds(1,amiao);
}
if(anumfun==2)
{
afen++;
if(afen==60)
afen=0;
write_sfm(6,afen);
write_com(0x80+0x40+6);
write_ds(3,afen);
}
if(anumfun==3)
{
ashi++;
if(ashi==24)
ashi=0;
write_sfm(3,ashi);
write_com(0x80+0x40+3);
write_ds(5,ashi);
}
}
}
if(anumfun!=0)
{
if(timesub==0)
{
delay(5);
while(!timesub);
if(anumfun==1)
{
amiao--;
if(amiao==-1)
amiao=59;
write_sfm(9,amiao);
write_com(0x80+0x40+9);
write_ds(1,amiao);
}
if(anumfun==2)
{
afen--;
if(afen==-1)
afen=59;
write_sfm(6,afen);
write_com(0x80+0x40+6);
write_ds(3,afen);
}
if(anumfun==3)
{
ashi--;
if(ashi==-1)
ashi=23;
write_sfm(3,ashi);
write_com(0x80+0x40+3);
write_ds(5,ashi);
}
}
}
}
void init(){
EA=1;//开总中断
EX0=1;//开外部中断0
IT0=1;//设定触发方式为负跳变沿有效
lcden=0;//选通液晶显示屏
ledrw=0;//设定液晶显示屏的读写方式为读
write_com(0x38);//设置液晶显示模式为16*2显示,5*7点阵,8位数据接口 write_com(0x0c);//打开显示,并使光标不显示也不闪烁
write_com(0x06);//光标指针每次自动加1
write_com(1);//清屏
write_com(0x80);//送地址指针
for(num=0;num<16;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);//写到第二行
for(num=0;num<11;num++)
{
write_date(table1[num]);
delay(5);
}
write_ds(0x0a,0x20);//开启时钟芯片振荡器
write_ds(0x0b,0x26);//开启闹钟
read_ds(0x0c);//读取时钟芯片c寄存器
}
void main(){
init();
while(1)
{
keyscan();
set_alarm();
if(flag1==1)
didi();
if(flag==0)
{
//读取时间
miao=read_ds(0x00);
fen=read_ds(0x02);
shi=read_ds(0x04);
yue=read_ds(0x08);
ri=read_ds(0x07);
nian=read_ds(0x09);
week=read_ds(0x06);
//写入液晶显示屏
write_sfm(9,miao);
write_sfm(6,fen);
write_sfm(3,shi);
write_nyr(2,nian);
write_nyr(5,yue);
write_nyr(8,ri);
write_zhou(0x0f,week);
}
}
}
void exter() interrupt 0{
flag1=1;
read_ds(0x0c);//读时钟芯片c寄存器。

清除irp }
最终实验板:。

相关文档
最新文档