基于51单片机的万年历的设计 联系客服

发布时间 : 星期三 文章基于51单片机的万年历的设计更新完毕开始阅读0658c46d0a1c59eef8c75fbfc77da26925c596d2

单片机实训报告

//如果阳历的月大于2 且该年的2月为闰月,天数加1 //闰年指的就是阳历有闰日或阴历有闰月的一年; //阳历四年一闰,在二月加一天,这一天叫做闰日:

//农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。 if( ( month <= 2 ) || ( year % 0x04!= 0) ) day_number-=1; // day_number ++;

// if ((month<2)||(year%0x04!=0)) // day_number-=1;

//判断阳历日 在春节(正月初一) 之前 还是 之后

if( day_number >= temp3 ) //阳历在春节之后 或者 春节当日 {

day_number -= temp3; month = 1;

month_point = 1; // month_point 为月份指向,阳历日在春季前就是春季

flag_month = get_moon_day( month_point, calendar_address ); //检查该阴历月的大小 大月返回1 小月返回0 flag_year = 0; /* if( flag_month )

temp1 = 30; //大月30天 else

temp1 = 29; //小月29天 */

if (flag_month==0) {temp1=29;} else{temp1=30;}

//闰月所在的月分

temp2 = year_code[ calendar_address ] & 0xf0; temp2 >>= 4; //提取高四位 假如是0 表示没有闰月

while( day_number >= temp1 ) {

day_number -= temp1; month_point ++;

if( month == temp2 ) {

flag_year = ~ flag_year; if( flag_year == 0 ) month +=1; } else

month ++ ;

- 15 -

单片机实训报告

flag_month = get_moon_day( month_point, calendar_address ); if( flag_month ) temp1 = 30; else

temp1 = 29; }

day = day_number + 1; }

else //阳历在春节之前使用以下代码进行运算 {

temp3 -= day_number; if( year == 0 )

{ year = 0xe3; c_flag = 1; } else

year -= 1;

calendar_address -= 3; month = 0xc;

temp2 = year_code[ calendar_address ] & 0xf0; temp2 >>= 4; //提取高4位 flag_year=0; if( temp2 == 0 )

month_point = 12; else

month_point = 13; //flag_year = 0;

flag_month = get_moon_day( month_point, calendar_address ); if( flag_month ) temp1 = 30; else

temp1 = 29;

while( temp3 > temp1 ) {

temp3 -= temp1; month_point --;

if( flag_year == 0 ) month -=1;

if( month == temp2 ) flag_year = ~ flag_year;

flag_month = get_moon_day( month_point, calendar_address ); if( flag_month ) temp1 = 0x1e; else

temp1 = 0x1d;

- 16 -

单片机实训报告

}

day = temp1 - temp3 + 1; }

//HEX->BCD ,运算结束后,把数据转换为BCD数据 temp1 = year / 10; temp1 <<= 4;

clock_moon[2] = temp1 | ( year % 10 );

temp1 = month / 10; temp1 <<= 4;

clock_moon[1] = temp1 | ( month % 10 );

temp1 = day / 10; temp1 <<= 4;

clock_moon[0] = temp1 | ( day % 10 ); Lcd_Lunar_Calendar( clock_moon ); }

/******************************************************************** 算法: ( 日期 + 年份 + 所过闰年 + 月校正 ) / 7 的余数就是星期 如果是闰年又不到 3 月份上述之和 要减一天 再

********************************************************************/ void Week_Convert( bit c, uchar * clock_time ) {

uchar year, month, day; //定义 年 月 天 uchar temp;

clock_time += 3; //指向日

day = ( * clock_time >> 4 ) * 10 + ( *clock_time & 0x0f ); //BCD转换十进制

clock_time ++; //指向月

month = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); clock_time ++; //指向年

year = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f );

if( c == 0 ) //如果为21世纪,年份数加100 year += 100;

temp = year / 4; //所过闰年数只算1900年之后的 temp = year + temp;

temp = temp % 0x07; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据

temp = temp + day + table_week[ month - 1 ]; if( ( year % 4 == 0 ) && ( month <3 ) ) temp -=1;

- 17 -

单片机实训报告

Lcd_Week( temp % 7 ); }

/*******************************************************************/ #endif

4. 时钟控制程序

#ifndef _REAL_TIMER_DS1302 #define _REAL_TIMER_DS1302 /*****************************预定义**************************************/ #define uchar unsigned char

#define uint unsigned int/***************************DS1302管脚配置****************************/ sbit clock_rst = P2^4;

sbit clock_io = P2^3; sbit clock_sclk= P2^2;

/*********************为了编程方便定义的位变量**********************/ sbit ACC0 = ACC ^ 0; sbit ACC7 = ACC ^ 7;

#define second_address 0x80 #define minute_address 0x82 #define hour_address 0x84 #define day_address 0x86 #define month_address 0x88 #define year_address 0x8C

/******************************************************************** * 功 能:向时钟DS1302写入一个字节

********************************************************************/ void Clock_Write_Byte(uchar temp) {

uchar i; ACC=temp;

for(i=8; i>0; i--) {

clock_io = ACC0; //相当于汇编中的 RRC clock_sclk = 1; clock_sclk = 0; ACC = ACC >> 1; } }

/******************************************************************** * 功 能:从时钟DS1302读取一个字节

********************************************************************/ uchar Clock_Read_Byte(void) {

- 18 -