跪求个利用51单片机1602显示屏DS1302做的万年历c编程序,带有公历,农历,星期,时间功能,一定要有农历

跪谢

第1个回答  推荐于2016-11-26
农历计算方式,
///月份数据表
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=temp1*10+temp2;
temp1=month/16;
temp2=month%16;
month=temp1*10+temp2;
temp1=day/16;
temp2=day%16;
day=temp1*10+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=temp1*10+temp2;
temp1=month/16;
temp2=month%16;
month=temp1*10+temp2;
temp1=day/16;
temp2=day%16;
day=temp1*10+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;
}本回答被提问者采纳

跪求个利用51单片机1602显示屏DS1302做的万年历c编程序,带有公历,农历...
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为世纪...

基于51单片机,DS1302,1602实现万年历(年月日时分秒)及闹钟功能的C程序...
5.经过分析GPS数据,利用算法缩短了解析时间在秒级时间内就能获取到GPS时间数据(正常情况下,完成定位需要几分钟以上)6.(亮点)利用算法自动计算星期参数和农历参数,程序内部算法输入任何阳历日期数据即可得到准确的星期数据和农历数据 7.利用12864串口工作模式,节省了8个IO 8.可根据需求进行功能定制 ☆...

跪求51单片机+12864液晶+1302时钟制成的万年历c程序?
void Write1302(unsigned char ucAddr, unsigned char ucDa) \/\/ucAddr: DS1302地址, ucData: 要写的数据{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); \/\/ 地址,命令 DS1302InputByte(ucDa); \/\/ 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0;} unsigned ...

基于51单片机的数字电子钟万年历闰年判断闹钟整点报时设计
基于51单片机设计的电子钟万年历闹钟满足以下功能:显示年、月、日、时、分、秒、星期、农历,通过按键设置闹钟与报警,调整时间并判断平年或闰年,共有4个按键实现设置时间\/闹钟、时间加、时间减、设置切换,整点时有蜂鸣器提醒。系统主要由51单片机、DS1302时钟芯片、按键模块、LCD1602显示以及电源构成。AT...

基于51单片机的时钟万年历—可农历显示
基于51单片机的时钟万年历是一款功能强大的时间显示设备,它不仅能够显示年、月、日、时、分、秒、星期,还能显示农历,满足不同用户的需求。通过按键,用户可以设置闹钟和报警,调整时间,并了解当前年份是否为平年或闰年。硬件方面,该万年历采用STC89C52单片机为核心,配合其他必要的电子元件,如万用板、...

跪求:液晶LCD1602显示时钟的C程序!
顶层文件 万年历.C #include<reg51.h> #include "LCD1602.h" #include "DS1302.h" #define uchar unsigned char #define uint unsigned int sbit speaker=P2^4; bit key_flag1=0,key_flag2=0; SYSTEMTIME adjusted; uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0; ucha...

单片机使用时钟芯片1302做万年历,怎么改变其中的时间以调时?
1.将改变的时间值重新写入ds1302的时钟寄存器,注意在写入之前先要禁用写保护,当初我在写这个时候,忽视了这一点,一直写不进去,差点崩溃了。2.还要注意时间是24\/12时的模式,如果你的万年历可以设定时间显示的模式时,要注意在24模式下,和12模式下的写入时位寄存器的不同。

基于单片机多功能数字钟
TEMP EQU 50H ;用做存储单元显示子程序(DISPLAY)里用到 BIJIAO EQU 51H ;加一子程序(JIAYI)中用到 ZDRQO EQU 55H ;中断加一程序中用到 ZDRQT EQU 56H ;中断加一程序中用到 ZDRQS EQU 57H ;中断加一程序中用到 ZDRQF EQU 58H ;中断加一程序中用到 DIZHI EQU 59H ;键盘(JIANPAN)子程序里用到 ...

更好最全的万年历下载,实用万年历电脑版
题目:1602A液晶显示万年历设计 一、设计任务:本设计由数据显示模块、温度采集模块、时间处理模块和调整设置模块四个模块组成。系统以AT89S52单片机为,以串行时钟日历芯片DS1302记录日历和时间,它可以对年、月、日、时、分、秒进行计时,还具有闰年补偿等多种功能。温度采集选用DS18B20芯片,万年历采用直观...

求助ds1302+6位数码管万年历
ET0 = 1; \/*开定时器0中断*\/ return;} \/ 函 数 名:RTInputByte()功 能:实时时钟写入一字节 说 明:往DS1302写入1Byte数据 (内部函数)入口参数:d 写入的数据 返 回 值:无 设 计:zhaojunjie 日 期:2002-03-19 修 改: 日 期:\/ void RTInputByte...

相似回答