求不需要时钟芯片单片万年历LCD1602显示程序。坐等,急急急 基于STC89C52

求不需要时钟芯片单片万年历LCD1602显示程序。坐等,急急急 基于STC89C52,第1张

这是一个1602计时的程序,稍微改一下就是万年历了

//12MHz

#include<AT89X51.H>

unsigned char Sec,Min,Hour

#define DB P2

#define RS P3_0

#define RW P3_1

#define E  P3_2

void delay1ms(void)   //误差 0us

{

    unsigned char a,b,c

    for(c=1c>0c--)

        for(b=142b>0b--)

            for(a=2a>0a--)

}

void nop(unsigned char time){while(time--)}

void LCD_WriteCmd(unsigned char cmd)

{

RS=0

DB=cmd

E=0

nop(5)

E=1

nop(5)

}

void LCD_WriteData(unsigned char dat)

{

RS=1

DB=dat

E=0

nop(5)

E=1

nop(5)

}

void Init1602(void)

{

RW=0

LCD_WriteCmd(0x38)

delay1ms()

LCD_WriteCmd(0x0c)

delay1ms()

LCD_WriteCmd(0x06)

delay1ms()

LCD_WriteCmd(0x01)

delay1ms()

}

void LCD_Clear()

{

LCD_WriteCmd(0x01)

delay1ms()

}

void LCD_SetAddress(unsigned char x,unsigned char y)

{

if(y)

LCD_WriteCmd(0xc0+x)

else

LCD_WriteCmd(0x80+x)

delay1ms()

}

void LCD_DrawChar(unsigned char dat)

{

LCD_WriteData(dat)

delay1ms()

}

void InitTimer0(void)

{

TMOD = 0x01

TH0 = 0x3C

TL0 = 0x0B0

EA = 1

ET0 = 1

TR0 = 1

}

void main(void)

{

InitTimer0()//初始化50ms定时器中断

Init1602()//初始化1602

LCD_Clear()//1602清屏

while(1)

{

LCD_SetAddress(4,0)//显示时间

LCD_DrawChar(Hour/10+'0')

LCD_DrawChar(Hour%10+'0')

LCD_DrawChar(':')

LCD_DrawChar(Min/10+'0')

LCD_DrawChar(Min%10+'0')

LCD_DrawChar(':')

LCD_DrawChar(Sec/10+'0')

LCD_DrawChar(Sec%10+'0')

}

}

void Timer0Interrupt(void) interrupt 1

{

static unsigned char cont

TH0 += 0x3C

TL0 += 0x0B0

if(++cont==20)//20*50ms=1s

{

cont=0

if(++Sec==60)

{

Sec=0

if(++Min==60)

{

Min=0

if(++Hour==24)

{

Hour=0

}

}

}

}

}

效果:

农历计算方式,

///月份数据

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=0x63c=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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11060438.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存