好文档 - 专业文书写作范文服务资料分享网站

基于51单片机的万年历的设计

天下 分享 时间: 加入收藏 我要投稿 点赞

单片机实训报告

uchar clock_moon[3]; //定义阴历

clock_time += 3; //指向日

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

clock_time ++; //指向月

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

clock_time ++; //指向年

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

//定位日历地址 if( c_flag == 0 )

calendar_address = ( year + 99 ) * 3; else

calendar_address = ( year - 1 ) * 3;

//春节(正月初一)所在的阳历月份

temp1 = year_code[ calendar_address + 2 ] & 0x60; //Bit6~~Bit5:春节所在的阳历月份 temp1 >>= 5 ;

//春节(正月初一)所在的阳历日期

temp2 = year_code[ calendar_address + 2 ] & 0x1f; //Bit4~~Bit0:春节所在的阳历日期

//计算春节(正月初一)离当年元旦{ 1月1日(阳历) }的天数;春节只会在阳历的1月 或 2月 /*if( temp1 == 1 ) temp3 = temp2 - 1; else

temp3 = temp2 + 31 - 1; */

temp3=temp2-1;

if(temp1!=1) temp3+=0x1f;

//计算阳历月离当年元旦{ 1月1日(阳历) }的天数 if( month < 10 )

{day_number = day_code1[ month - 1 ] + day ;} else

{day_number = day_code2[ month - 10 ] + day ;}

- 14 -

单片机实训报告

//如果阳历的月大于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 -

基于51单片机的万年历的设计

单片机实训报告ucharclock_moon[3];//定义阴历clock_time+=3;//指向日day=(*clock_time>>4)*10+(*clock_time&0x0f);//BCD转换十进制clock_time++;//指向月<
推荐度:
点击下载文档文档为doc格式
08wxw495wc3ibqw7s1xb7s7tu43p3900tsi
领取福利

微信扫码领取福利

微信扫码分享