单片机万年历程序带农历和闹钟Word文档下载推荐.docx
《单片机万年历程序带农历和闹钟Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《单片机万年历程序带农历和闹钟Word文档下载推荐.docx(77页珍藏版)》请在冰豆网上搜索。
TH0=0x3c;
TL0=0XB0;
//延时50ms
TR0=1;
//启动Timer0
count++;
if(count==20)//鸣叫1秒
{
bell=~bell;
flag++;
}
if(flag==6)
flag=0;
}
}
Timer2_Servie()interrupt5
中断效劳程序整点报时一分钟
voidTimer3_Service()interrupt5
staticucharcount;
TF2=0;
//软件清除中断标志
if(in==1)
//计算清0
TR2=0;
//关闭Timer2
bell=1;
//关闭蜂鸣器
if(count==120)//一分钟后关闭报警
}
/******************************************************************************
*函数名称:
main()
*功能:
*入口参数:
*出口参数:
********************************************************************************/
voidmain(void)
ucharclock_time[7]={0x00,0x17,0x12,0x14,0x12,0x08};
//概念时刻变量秒分时日月年
ucharalarm_time[2]={0,0};
//闹钟设置alarm_time[0]:
分钟alarm_time[1]:
小时
uchartemperature[2];
//概念温度变量temperature[0]低8位temperature[1]高8位
Lcd_Initial();
//LCD初始化
Clock_Initial(clock_time);
//时钟初试化
/***********************中断初始化***************************/
EA=1;
//开总中断
ET0=1;
//Timer0开中断
ET2=1;
//Timer2开中断
TMOD=0x01;
//Timer0工作方式1
RCAP2H=0x3c;
RCAP2L=0xb0;
//Timer2延时50ms
while
(1)
switch(Key_Scan())
caseup_array:
//
Key_Idle();
break;
casedown_array:
caseclear_array:
{
casefunction_array:
Key_Function(clock_time,alarm_time);
casenull:
Clock_Fresh(clock_time);
//时刻刷新
Lcd_Clock(clock_time);
//时刻显示
Sensor_Fresh(temperature);
//温度更新
Lcd_Temperture(temperature);
//温度显示
Calendar_Convert(0,clock_time);
Week_Convert(0,clock_time);
//整点报时
if((*clock_time==0x59)&
&
(*(clock_time+1)==0x59))
bell=0;
TR2=1;
//启动Timer2
//闹钟报警
if(*alarm_time==*(clock_time+1))//分钟相吻合
if(*(alarm_time+1)==*(clock_time+2))//小时相吻合
#ifndef_SUN_MOON
#define_SUN_MOON
/*************************************************************************/
/********************************************************************************
get_moon_day(ucharmonth_p,uinttable_addr)
读取数据表中农历的大月或小月,若是大月返回1,小月返回0
*********************************************************************************/
bitget_moon_day(ucharmonth_p,uintcalendar_address)
uchartemp;
switch(month_p)
case1:
{temp=year_code[calendar_address]&
0x08;
if(temp==0)return(0);
elsereturn
(1);
case2:
0x04;
case3:
0x02;
case4:
0x01;
case5:
{temp=year_code[calendar_address+1]&
0x80;
case6:
0x40;
case7:
0x20;
case8:
0x10;
case9:
case10:
case11:
case12:
case13:
{temp=year_code[calendar_address+2]&
/**************************************************************************
voidCalendar_Convert(uchar*clock_time)
输入BCD的阳历数据,输出BCD阴历数据(1901-2099)
c_flag:
阳历的世纪标志clock_time:
时钟地址
无
*说明:
c_flag=0:
21世纪c_flag=1:
19世纪
voidCalendar_Convert(ucharc_flag,uchar*clock_time)
bitflag_month,flag_year;
ucharyear,month,day,month_point;
//概念年月天
uchartemp1,temp2,temp3;
uintcalendar_address;
//概念农历地址
uintday_number;
ucharclock_moon[3];
//概念阴历
clock_time+=3;
//指向日
day=(*clock_time>
>
4)*10+(*clock_time&
0x0f);
//BCD转换十进制
clock_time++;
//指向月
month=(*clock_time>
4)*10+(*clock_time&
//指向年
year=(*clock_time>
//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;
temp3=temp2+31-1;
//计算阳历月离昔时元旦{1月1日(阳历)}的天数
if(month<
10)
day_number=day_code1[month-1]+day-1;
day_number=day_code2[month-10]+day-1;
//若是阳历的月大于2且该年的2月为闰月,天数加1
//闰年指的确实是阳历有闰日或阴历有闰月的一年;
//阳历四年一闰,在二月加一天,这一天叫做闰日:
//农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。
if((month>
2)&
(year%4==0))
day_number++;
//判定阳历日在春节(正月初一)之前仍是以后
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天
temp1=29;
//小月29天
//闰月所在的月分
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;
month++;
day=day_number+1;
else//阳历在春节之前利用以下代码进行运算
temp3-=day_number;
if(year==0)
{year=99;
c_flag=1;
year-=1;
calendar_address-=0x03;
month=12;
//提取高4位
if(temp2==0)
month_point=12;
month_point=13;
while(temp3>
temp1)
temp3-=temp1;
month_point--;
if(flag_year==0)
month-=1;
day=temp1-day_number+1;
//HEX->
BCD,运算终止后,把数据转换为BCD数据
temp1=year/10;
temp1<
<
clock_moon[2]=temp1|(year%10);
temp1=month/10;
clock_moon[1]=temp1|(month%10);
temp1=day/10;
clock_moon[0]=temp1|(day%10);
Lcd_Lunar_Calendar(clock_moon);
voidWeek_convert(uchar*clock_time)
输入BCD阳历数据;
输出BCD礼拜
算法:
(日期+年份+所过闰年+月校正)/7的余数确实是礼拜若是是闰年又不到3月份上述之和要减一天再
voidWeek_Convert(bitc,uchar*clock_time)
ucharyear,month,day;
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;
Lcd_Week(temp%7);
/********************************************************************************/
#endif
#ifndef_CHARACTER
#define_CHARACTER
#defineucharunsignedchar
/********************************************************************************************
*内容:
0123456789:
-
*大小:
8X16字符
*********************************************************************************************/
ucharcodeletter_logo[12][16]={
/*--文字:
0--*/
/*