51单片机实现万年历程序文件

51单片机实现万年历程序文件
51单片机实现万年历程序文件

51单片机实现万年历

利用AT89S52单片机的P0口来和另外几个口来控制1602液晶的显示和P1口还有其它口来控制ds12887时钟芯片。设置四个按键,1个定义为时间设置功能键,一个定义为闹钟设置功能键,另外两个用来调节时间的增减。

原理图:

pcb图:

源程序:

#include

#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;

void delay(uint x){

uchar i,j;

for(i=x;i>0;i--)

for(j=110;j>0;j--);

}

void didi()

{

beep=0;

delay(1000);

beep=1;

delay(1000);

}

void write_(uchar ){

lcdrs=0;

P0=;

delay(5);

lcden=1;

delay(20);

lcden=0;

}

void write_date(uchar date){

lcdrs=1;

P0=date;

delay(5);

lcden=1;

delay(20);

lcden=0;

}

void write_sfm(uchar add,uchar date){ uchar shi,ge;

shi=date/10;

ge=date%10;

write_(0x80+0x40+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void write_nyr(uchar add,uchar date){ uchar shi,ge;

shi=date/10;

ge=date%10;

write_(0x80+add);

write_date(0x30+shi);

write_date(0x30+ge);

}

void write_zhou(uchar add,uchar date) {

write_(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_(0x80+0x40+0x0a);

write_(0x0f);

}

if(numfun==2)

{

write_(0x80+0x40+0x07);

write_(0x0f);

}

if(numfun==3)

{

write_(0x80+0x40+0x04);

write_(0x0f);

}

if(numfun==4)

{

write_(0x80+0x0f);

write_(0x0f);

}

if(numfun==5)

{

write_(0x80+0x09);

write_(0x0f);

}

if(numfun==6)

{

write_(0x80+0x06);

write_(0x0f);

}

if(numfun==7)

{

write_(0x80+0x03);

write_(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_(0x80+0x40+9);

write_ds(0,miao);

}

if(numfun==2)

{

fen++;

if(fen==60)

fen=0;

write_sfm(6,fen);

write_(0x80+0x40+6);

write_ds(2,fen);

}

if(numfun==3)

{

shi++;

if(shi==24)

shi=0;

write_sfm(3,shi);

write_(0x80+0x40+3);

write_ds(4,shi);

}

if(numfun==4)

{

week++;

if(week==8)

week=1;

write_zhou(0x0f,week);

write_(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_(0x80+0x08);

write_ds(7,ri);

}

if(numfun==6)

{

yue++;

if(yue==13)

yue=0;

write_nyr(5,yue);

write_(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_(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_(0x80+0x40+9);

write_ds(0,miao);

}

if(numfun==2)

{

fen--;

if(fen==-1)

fen=59;

write_sfm(6,fen);

write_(0x80+0x40+6);

write_ds(2,fen);

}

if(numfun==3)

{

shi--;

if(shi==-1)

shi=23;

write_sfm(3,shi);

write_(0x80+0x40+3);

write_ds(4,shi);

}

if(numfun==4)

{

week--;

if(week==0)

week=7;

write_zhou(0x0f,week);

write_(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_(0x80+0x08);

write_ds(7,ri);

}

if(numfun==6)

{

yue--;

if(yue==-1)

yue=12;

write_nyr(5,yue);

write_(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_(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_(0x80+0x40+0x0a);

write_(0x0f);

}

if(anumfun==2)

{

flag=1;

write_(0x80+0x40+0x07);

write_(0x0f);

}

if(anumfun==3)

{

flag=1;

write_(0x80+0x40+0x04);

write_(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_(0x80+0x40+9);

write_ds(1,amiao);

}

if(anumfun==2)

{

afen++;

if(afen==60)

afen=0;

write_sfm(6,afen);

write_(0x80+0x40+6);

write_ds(3,afen);

}

if(anumfun==3)

{

ashi++;

if(ashi==24)

ashi=0;

write_sfm(3,ashi);

write_(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_(0x80+0x40+9);

write_ds(1,amiao);

}

if(anumfun==2)

{

afen--;

if(afen==-1)

afen=59;

write_sfm(6,afen);

write_(0x80+0x40+6);

write_ds(3,afen);

}

if(anumfun==3)

{

ashi--;

if(ashi==-1)

ashi=23;

write_sfm(3,ashi);

write_(0x80+0x40+3);

write_ds(5,ashi);

}

}

}

}

void init(){

EA=1;//开总中断

EX0=1;//开外部中断0

IT0=1;//设定触发方式为负跳变沿有效

lcden=0;//选通液晶显示屏

ledrw=0;//设定液晶显示屏的读写方式为读

write_(0x38);//设置液晶显示模式为16*2显示,5*7点阵,8位数据接口 write_(0x0c);//打开显示,并使光标不显示也不闪烁

write_(0x06);//光标指针每次自动加1

write_(1);//清屏

write_(0x80);//送地址指针

for(num=0;num<16;num++)

{

write_date(table[num]);

delay(5);

}

write_(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 }

最终实验板:

相关主题
相关文档
最新文档