#include<reg52h>
#define uint unsigned int
#define uchar unsigned char
sbit ACC_7=ACC^7; //位寻址寄存器定义
sbit rs=P3^5;
sbit en=P3^4;
sbit sclk=P2^0;
sbit io=P2^5;
sbit ce=P2^4;
sbit wd18b20=P2^7;
sbit beep=P1^7;
sbit led=P3^7;
sbit s1=P1^0;
sbit s2=P1^1;
sbit s3=P1^2;
sbit s4=P1^3;
sbit s5=P1^4;
char yue,ri,shi,fen,miao;
uchar s1num=0,a=0; //a是s1num所对应的结果
uchar b=0x80+0x40;
uchar code table1[5]={
0x56,0x34,0x12,0x22,0x02};
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=114;j>0;j--);
}
void write_com(uchar com) //1602写命令
{
rs=0;
en=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_data(uchar dat) //1602写数据
{
rs=1;
en=0;
P0=dat;
delay(5);
en=1;
delay(5);
en=0;
}
void w1302(uchar dz,uchar sj) //1302写,先地址,后数据
{
uchar i,j;
ce=0;
sclk=0;
ce=1;
for(i=8;i>0;i--)
{
sclk=0;
j=dz;
io=(bit)(j&0x01);
dz>>=1;
sclk=1;
}
for(i=8;i>0;i--)
{
sclk=0;
j=sj;
io=(bit)(j&0x01);
dz>>=1;
sclk=1;
}
ce=0;
}
uchar r1302(uchar dz) //读取数据函数
{
uchar i,j,sj1,sj2;
ce=0;
sclk=0;
ce=1;
for(i=8;i>0;i--)
{
sclk=0;
j=dz;
io=(bit)(j&0x01);
dz>>=1;
sclk=1;
}
for(i=8;i>0;i--)
{
ACC_7=io;
sclk=1;
ACC>>=1;
sclk=0;
}
ce=0;
sj1=ACC;
sj2=sj1/16;
sj1=sj1%16;
sj1=sj1+sj210;
return(sj1);
}
void init() //初始化函数
{
uchar a,b=0x80;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01); //1602初始化
write_com(0x80+0x40+2);
write_data('/');
write_com(0x80+0x40+5);
write_data('-');
write_com(0x80+0x40+8);
write_data(':');
write_com(0x80+0x40+11);
write_data(':');
w1302(0x8e,0x00); //1302初始化
for(a=0;a<5;a++)
{
w1302(b,table1[a]);
b+=2;
}
w1302(0x8e,0x80);
}
void shuax(uchar dz1602,uchar dz1302) //刷新时间函数
{
uchar sj,shi,ge;
sj=dz1302;
shi=sj/10;
ge=sj%10;
write_com(dz1602);
write_data(0x30+shi);
write_data(0x30+ge);
}
void keyscan()
{
if(s1==0)
{
delay(5);
if(s1==0)
{
s1num++;
while(!s1);
switch(s1num)
{
case 1:a=1;
write_com(0x80);
write_data('y');
break;
case 2:s1num=0;
a=0;
write_com(0x0c);
write_com(0x80);
write_data(' ');
w1302(0x8e,0x00);
w1302(0x80,miao);
w1302(0x82,fen);
w1302(0x84,shi);
w1302(0x86,ri);
w1302(0x88,yue);
w1302(0x8e,0x80);
break;
}
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
b=b+3;
write_com(b);
write_com(0x0f);
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
b=b-3;
write_com(b);
write_com(0x0f);
}
}
if(s4==0)
{
delay(5);
if(s4==0)
{
while(!s4);
switch(b)
{
case 0x80+0x40:yue++;
if(yue==13)
yue=1;
w1302(0x8e,0x00);
w1302(0x88,yue);
w1302(0x8e,0x80);
shuax(0x80+0x40,yue);
break;
case 0x80+0x40+3:ri++;
if(ri==32)
ri=1;
w1302(0x8e,0x00);
w1302(0x86,ri);
w1302(0x8e,0x80);
shuax(0x80+0x40+3,ri);
break;
case 0x80+0x40+6:shi++;
if(shi==24)
shi=0;
w1302(0x8e,0x00);
w1302(0x84,shi);
w1302(0x8e,0x80);
shuax(0x80+0x40+6,shi);
break;
case 0x80+0x40+9:fen++;
if(fen==60)
fen=0;
w1302(0x8e,0x00);
w1302(0x82,fen);
w1302(0x8e,0x80);
shuax(0x80+0x40+9,fen);
break;
case 0x80+0x40+12:miao++;
if(miao==60)
miao=0;
w1302(0x8e,0x00);
w1302(0x80,miao);
w1302(0x8e,0x80);
shuax(0x80+0x40+12,miao);
break;
}
}
}
if(s5==0)
{
delay(5);
if(s5==0)
{
while(!s5);
switch(b)
{
case 0x80+0x40:yue--;
if(yue==0)
yue=12;
shuax(0x80+0x40,yue);
break;
case 0x80+0x40+3:ri--;
if(ri==0)
ri=31;
shuax(0x80+0x40+3,ri);
break;
case 0x80+0x40+6:shi--;
if(shi==-1)
shi=23;
shuax(0x80+0x40+6,shi);
break;
case 0x80+0x40+9:fen--;
if(fen==-1)
fen=59;
shuax(0x80+0x40+9,fen);
break;
case 0x80+0x40+12:miao--;
if(miao==-1)
miao=59;
shuax(0x80+0x40+12,miao);
break;
}
}
}
}
}
void main()
{
init();
while(1)
{
yue=r1302(0x89);
ri=r1302(0x87);
shi=r1302(0x85);
fen=r1302(0x83);
miao=r1302(0x81);
keyscan();
shuax(0x80+0x40,yue);
shuax(0x80+0x40+3,ri);
shuax(0x80+0x40+6,shi);
shuax(0x80+0x40+9,fen);
shuax(0x80+0x40+12,miao);
}
}
农历计算方式,
///月份数据表
code uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};
code uint day_code2[3]={0x111,0x130,0x14e};
/
函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
/
bit c_moon;
data uchar year_moon,month_moon,day_moon,week;
/子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0/
bit get_moon_day(uchar month_p,uint table_addr)
{
uchar temp;
switch (month_p)
{
case 1:{temp=year_code[table_addr]&0x08;
if (temp==0)return(0);else return(1);}
case 2:{temp=year_code[table_addr]&0x04;
if (temp==0)return(0);else return(1);}
case 3:{temp=year_code[table_addr]&0x02;
if (temp==0)return(0);else return(1);}
case 4:{temp=year_code[table_addr]&0x01;
if (temp==0)return(0);else return(1);}
case 5:{temp=year_code[table_addr+1]&0x80;
if (temp==0) return(0);else return(1);}
case 6:{temp=year_code[table_addr+1]&0x40;
if (temp==0)return(0);else return(1);}
case 7:{temp=year_code[table_addr+1]&0x20;
if (temp==0)return(0);else return(1);}
case 8:{temp=year_code[table_addr+1]&0x10;
if (temp==0)return(0);else return(1);}
case 9:{temp=year_code[table_addr+1]&0x08;
if (temp==0)return(0);else return(1);}
case 10:{temp=year_code[table_addr+1]&0x04;
if (temp==0)return(0);else return(1);}
case 11:{temp=year_code[table_addr+1]&0x02;
if (temp==0)return(0);else return(1);}
case 12:{temp=year_code[table_addr+1]&0x01;
if (temp==0)return(0);else return(1);}
case 13:{temp=year_code[table_addr+2]&0x80;
if (temp==0)return(0);else return(1);}
}
}
/
函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)
调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据
/
void Conversion(bit c,uchar year,uchar month,uchar day)
{ //c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
uchar temp1,temp2,temp3,month_p;
uint temp4,table_addr;
bit flag2,flag_y;
temp1=year/16; //BCD->hex 先把数据转换为十六进制
temp2=year%16;
year=temp110+temp2;
temp1=month/16;
temp2=month%16;
month=temp110+temp2;
temp1=day/16;
temp2=day%16;
day=temp110+temp2;
//定位数据表地址
if(c==0)
{
table_addr=(year+0x64-1)0x3;
}
else
{
table_addr=(year-1)0x3;
}
//定位数据表地址完成
//取当年春节所在的公历月份
temp1=year_code[table_addr+2]&0x60;
temp1=_cror_(temp1,5);
//取当年春节所在的公历月份完成
//取当年春节所在的公历日
temp2=year_code[table_addr+2]&0x1f;
//取当年春节所在的公历日完成
// 计算当年春年离当年元旦的天数,春节只会在公历1月或2月
if(temp1==0x1)
{
temp3=temp2-1;
}
else
{
temp3=temp2+0x1f-1;
}
// 计算当年春年离当年元旦的天数完成
//计算公历日离当年元旦的天数,为了减少运算,用了两个表
//day_code1[9],day_code2[3]
//如果公历月在九月或前,天数会少于0xff,用表day_code1[9],
//在九月后,天数大于0xff,用表day_code2[3]
//如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1
//如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1
if (month<10)
{
temp4=day_code1[month-1]+day-1;
}
else
{
temp4=day_code2[month-10]+day-1;
}
if ((month>0x2)&&(year%0x4==0))
{ //如果公历月大于2月并且该年的2月为闰月,天数加1
temp4+=1;
}
//计算公历日离当年元旦的天数完成
//判断公历日在春节前还是春节后
if (temp4>=temp3)
{ //公历日在春节后或就是春节当日使用下面代码进行运算
temp4-=temp3;
month=0x1;
month_p=0x1; //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月
flag2=get_moon_day(month_p,table_addr);
//检查该农历月为大小还是小月,大月返回1,小月返回0
flag_y=0;
if(flag2==0)temp1=0x1d; //小月29天
else temp1=0x1e; //大小30天
temp2=year_code[table_addr]&0xf0;
temp2=_cror_(temp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月
while(temp4>=temp1)
{
temp4-=temp1;
month_p+=1;
if(month==temp2)
{
flag_y=~flag_y;
if(flag_y==0)
month+=1;
}
else month+=1;
flag2=get_moon_day(month_p,table_addr);
if(flag2==0)temp1=0x1d;
else temp1=0x1e;
}
day=temp4+1;
}
else
{ //公历日在春节前使用下面代码进行运算
temp3-=temp4;
if (year==0x0)
{
year=0x63;c=1;
}
else year-=1;
table_addr-=0x3;
month=0xc;
temp2=year_code[table_addr]&0xf0;
temp2=_cror_(temp2,4);
if (temp2==0)
month_p=0xc;
else
month_p=0xd; //
/month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12/
flag_y=0;
flag2=get_moon_day(month_p,table_addr);
if(flag2==0)temp1=0x1d;
else temp1=0x1e;
while(temp3>temp1)
{
temp3-=temp1;
month_p-=1;
if(flag_y==0)month-=1;
if(month==temp2)flag_y=~flag_y;
flag2=get_moon_day(month_p,table_addr);
if(flag2==0)temp1=0x1d;
else temp1=0x1e;
}
day=temp1-temp3+1;
}
c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据
temp1=year/10;
temp1=_crol_(temp1,4);
temp2=year%10;
year_moon=temp1|temp2;
temp1=month/10;
temp1=_crol_(temp1,4);
temp2=month%10;
month_moon=temp1|temp2;
temp1=day/10;
temp1=_crol_(temp1,4);
temp2=day%10;
day_moon=temp1|temp2;
}
/
/函数功能:输入BCD阳历数据,输出BCD星期数据(只允许1901-2099年)
调用函数示例:Conver_week(c_sun,year_sun,month_sun,day_sun)
如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);
c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世
纪,c_sun=1为19世纪
调用函数后,原有数据不变,读week得出阴历BCD数据
/
code uchar table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表
/
算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在
闰年又不到3 月份上述之和要减一天再除7
星期数为0
/
void Conver_week(bit c,uchar year,uchar month,uchar day)
{//c=0 为21世纪,c=1 为19世纪 输入输出数据均为BCD数据
uchar temp1,temp2;
temp1=year/16; //BCD->hex 先把数据转换为十六进制
temp2=year%16;
year=temp110+temp2;
temp1=month/16;
temp2=month%16;
month=temp110+temp2;
temp1=day/16;
temp2=day%16;
day=temp110+temp2;
if (c==0){year+=0x64;} //如果为21世纪,年份数加100
temp1=year/0x4; //所过闰年数只算1900年之后的
temp2=year+temp1;
temp2=temp2%0x7; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据
temp2=temp2+day+table_week[month-1];
if (year%0x4==0&&month<3)temp2-=1;
week=temp2%0x7;
}
#include<reg52h>
#include<defineh>
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void didi()
{
beep=0;
delay(50);
beep=1;
delay(100);
beep=0;
delay(50);
beep=1;
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
EA=1;
EX0=1;
IT0=1;
dula=0;
wela=0;
lcden=0;
// set_time();
set_alarm(14,13,10);
write_ds(0x0B,0x26);
read_ds(0x0c);
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(flag1==1)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
flag1=0;
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
flag1=0;
}
}
}
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
flag=1;
flag1=0;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
flag=0;
write_ds(0,miao);
write_ds(2,fen);
write_ds(4,shi);
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(1);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(1);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/ if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void write_ds(uchar add,uchar date)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;
ds_date=P0;
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}
void set_time()
{
write_ds(4,10);
write_ds(2,32);
}
void set_alarm(uchar ashi,uchar afen,uchar amiao)
{
write_ds(1,amiao);
write_ds(3,afen);
write_ds(5,ashi);
}
void main()
{
init();
while(1)
{
keyscan();
if(flag1==1)
didi();
if(flag==0)
{
miao=read_ds(0);
fen=read_ds(2);
shi=read_ds(4);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
}
}
}
void exter() interrupt 0
{ uchar c;
flag1=1;
c=read_ds(0x0c);
}
以上就是关于求一份用1602,AT89C52,DS1302做的时钟的C语言代码,或者求哪位大侠帮我看看这个程序有什么问题吧。。。全部的内容,包括:求一份用1602,AT89C52,DS1302做的时钟的C语言代码,或者求哪位大侠帮我看看这个程序有什么问题吧。。。、跪求个利用51单片机1602显示屏DS1302做的万年历c编程序,带有公历,农历,星期,时间功能,一定要有农历、急需电子时钟的设计,利用单片机AT89C52、时钟芯片DS1302、1602液晶显示器来控制的,要有c程序。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)