单片机万年历程序带农历和闹钟.docx
《单片机万年历程序带农历和闹钟.docx》由会员分享,可在线阅读,更多相关《单片机万年历程序带农历和闹钟.docx(77页珍藏版)》请在冰豆网上搜索。
单片机万年历程序带农历和闹钟
#include
#include
#include
#include
#include
#include
/*****************************预概念**************************************/
#defineucharunsignedchar
#defineuintunsignedint
/****************************************************************************/
sbitbell=P2^0;//概念蜂鸣器端口
sbitin=P2^7;//概念红外检测端口
/*****************************************************************************
*名称:
Timer0_Service()inturrupt1
*功能:
中断效劳程序整点报时3声嘟嘟的声音
*入口参数:
*出口参数:
*****************************************************************************/
voidTimer0_Service()interrupt1
{
staticucharcount=0;
staticucharflag=0;//记录鸣叫的次数
count=0;
TR0=0;//关闭Timer0
TH0=0x3c;
TL0=0XB0;//延时50ms
TR0=1;//启动Timer0
count++;
if(count==20)//鸣叫1秒
{
bell=~bell;
count=0;
flag++;
}
if(flag==6)
{
flag=0;
TR0=0;//关闭Timer0
}
}
/*****************************************************************************
*名称:
Timer2_Servie()interrupt5
*功能:
中断效劳程序整点报时一分钟
*入口参数:
*出口参数:
*****************************************************************************/
voidTimer3_Service()interrupt5
{
staticucharcount;
TF2=0;//软件清除中断标志
count++;
if(in==1)
{
count=0;//计算清0
TR2=0;//关闭Timer2
bell=1;//关闭蜂鸣器
}
if(count==120)//一分钟后关闭报警
{
count=0;//计算清0
TR2=0;//关闭Timer2
bell=1;//关闭蜂鸣器
}
}
/******************************************************************************
*函数名称:
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:
{
Key_Idle();
}
break;
caseclear_array:
{
Key_Idle();
}
break;
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))//小时相吻合
{
bell=0;
TR2=1;//启动Timer2
}
}
break;
}
}
}
#ifndef_SUN_MOON
#define_SUN_MOON
/*************************************************************************/
#defineucharunsignedchar
#defineuintunsignedint
/********************************************************************************
*名称:
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:
{temp=year_code[calendar_address]&0x04;if(temp==0)return(0);elsereturn
(1);}
case3:
{temp=year_code[calendar_address]&0x02;if(temp==0)return(0);elsereturn
(1);}
case4:
{temp=year_code[calendar_address]&0x01;if(temp==0)return(0);elsereturn
(1);}
case5:
{temp=year_code[calendar_address+1]&0x80;if(temp==0)return(0);elsereturn
(1);}
case6:
{temp=year_code[calendar_address+1]&0x40;if(temp==0)return(0);elsereturn
(1);}
case7:
{temp=year_code[calendar_address+1]&0x20;if(temp==0)return(0);elsereturn
(1);}
case8:
{temp=year_code[calendar_address+1]&0x10;if(temp==0)return(0);elsereturn
(1);}
case9:
{temp=year_code[calendar_address+1]&0x08;if(temp==0)return(0);elsereturn
(1);}
case10:
{temp=year_code[calendar_address+1]&0x04;if(temp==0)return(0);elsereturn
(1);}
case11:
{temp=year_code[calendar_address+1]&0x02;if(temp==0)return(0);elsereturn
(1);}
case12:
{temp=year_code[calendar_address+1]&0x01;if(temp==0)return(0);elsereturn
(1);}
case13:
{temp=year_code[calendar_address+2]&0x80;if(temp==0)return(0);elsereturn
(1);}
}
}
/**************************************************************************
*名称:
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&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;
//计算阳历月离昔时元旦{1月1日(阳历)}的天数
if(month<10)
day_number=day_code1[month-1]+day-1;
else
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天
else
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;
}
else
month++;
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=99;c_flag=1;}
else
year-=1;
calendar_address-=0x03;
month=12;
temp2=year_code[calendar_address]&0xf0;
temp2>>=4;//提取高4位
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=30;
else
temp1=29;
}
day=temp1-day_number+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);
}
/********************************************************************************
*名称:
voidWeek_convert(uchar*clock_time)
*功能:
输入BCD阳历数据;输出BCD礼拜
*入口参数:
*出口参数:
*说明:
算法:
(日期+年份+所过闰年+月校正)/7的余数确实是礼拜若是是闰年又不到3月份上述之和要减一天再
********************************************************************************/
voidWeek_Convert(bitc,uchar*clock_time)
{
ucharyear,month,day;//概念年月天
uchartemp;
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;
Lcd_Week(temp%7);
}
/********************************************************************************/
#endif
#ifndef_CHARACTER
#define_CHARACTER
/*****************************预概念**************************************/
#defineucharunsignedchar
#defineuintunsignedint
/********************************************************************************************
*内容:
0123456789:
-
*大小:
8X16字符
*********************************************************************************************/
ucharcodeletter_logo[12][16]={
/*--文字:
0--*/
/*