带农历及农历纪念日的万年历c程序.docx
《带农历及农历纪念日的万年历c程序.docx》由会员分享,可在线阅读,更多相关《带农历及农历纪念日的万年历c程序.docx(58页珍藏版)》请在冰点文库上搜索。
带农历及农历纪念日的万年历c程序
/*********************************************************************************************
程序名:
带字库12864LCC电子钟程序
器件:
STC89C52,LCD12864(内置汉字字库),18B20温度芯片,1302时钟芯片MCU晶振:
12MHZ
设计:
中国机器(仿造杜洋万年历程序并增加了农历功能)
功能:
显示公历年月日
农历年月日
星期(星期不调用DS1302内的数据,二十根据公历年月日推算的)
温度
时分秒
公历重大节日
农历纪念日与节日(用于提醒农历生日非常实用)
注:
1、当农历纪念日与公历纪念日碰到同一天,则按一秒的间隔轮流显示
2、20100226加入阳历大小月和平闰年判断,调日历时自动控制每个月份的天数
/*********************************************************************************************
/*********************************************************************************************/
//程序部分开始//
/****************************************************************************/
//头文件
#include
#include
/*****************************************************************************/
//定做PCB板的灯与扬声器定义
sbitled_back=P2^7;//背光控制(V2.1程序中加入了背光控制的硬件电路)
sbitbeep=P3^1;//扬声器
/*****************************************************************************/
//定做PCB板温度传感器引脚定义
sbitDQ=P2^0;//ds18B20*/
/*****************************************************************************/
//键盘引脚定义
sbitKEY_1=P1^7;//退出设置键,显示版本信息键
sbitKEY_2=P1^6;//上调键
sbitKEY_3=P1^5;//设置键
sbitKEY_4=P1^4;//减,下调键
sbitKEY_5=P1^3;//LED控制每次按动改变背光开关
/****************************************************************************/
//LCD接口定义
sbitRS=P1^0;//模式位,为0输入指令,为1输入数据
sbitRW=P1^1;//读写位,为0读,为1写
sbitE=P1^2;//使能位
#defineLcd_BusP0//数据总线
/*****************************************************************************/
//定义DS1302时钟接口
sbitclock_clk=P3^0;//ds1302_clk(时钟线)
sbitclock_dat=P3^6;//ds1302_dat(数据线)
sbitclock_Rst=P3^7;//ds1302_Rst(复位线)
/*****************************************************************************/
//定义累加器A中的各位
sbita0=ACC^0;
sbita1=ACC^1;
sbita2=ACC^2;
sbita3=ACC^3;
sbita4=ACC^4;
sbita5=ACC^5;
sbita6=ACC^6;
sbita7=ACC^7;
/****************************************************************************/
//定义全局变量
unsignedcharyy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
bitw=0;//调时标志位,=0时为走时状态,=1时为调时状态
staticunsignedcharmenu=0;//定义静态小时更新用数据变量
staticunsignedcharkeys=0;//定义静态小时更新用数据变量
staticunsignedchartimecount=0;//定义静态软件计数器变量
signedcharaddress,item,max,mini;
/****************************************************************************/
voidDelayM(unsignedinta){//延时函数1MS/次
unsignedchari;
while(--a!
=0){
for(i=0;i<125;i++);//一个;表示空语句,CPU空转。
}//i从0加到125,CPU大概就耗时1毫秒
}
/****************************************************************************/
/******************************************************************************/
//LCD驱动(DY12864CBL液晶显示屏并口驱动程序)
/******************************************************************************/
voidchk_busy(){//检查忙位(底层)
RS=0;
RW=1;
E=1;
Lcd_Bus=0xff;
while((Lcd_Bus&0x80)==0x80);
E=0;
}
/******************************************************************************/
voidwrite_com(unsignedcharcmdcode){//写命令到LCD(底层)
chk_busy();
RS=0;
RW=0;
E=1;
Lcd_Bus=cmdcode;
E=0;
}
/******************************************************************************/
voidwrite_data(unsignedcharDispdata){//写数据到LCD(底层)
chk_busy();
RS=1;
RW=0;
E=1;
Lcd_Bus=Dispdata;
E=0;
}
/******************************************************************************/
voidlcm_init(){//初始化LCD屏(被调用层)
write_com(0x30);//选择8bit数据流
write_com(0x0c);//开显示(无游标、不反白)
write_com(0x01);//清除显示,并且设定地址指针为00H
}
/*****************************************************************************/
voidlcm_w_word(unsignedchar*s){//向LCM发送一个字符串,长度64字符(一行)之内。
(被调用层)
while(*s>0){//应用:
lcm_w_word("您好!
"),直接显示:
您好!
write_data(*s);
s++;
}
}
/******************************************************************************/
voidlcm_w_test(biti,unsignedcharword){//写指令或数据(被调用层)
if(i==0){
write_com(word);//写指令或数据(0,指令)
}else{
write_data(word);//写指令或数据(1,数据)
}
}
/******************************************************************************/
voidlcm_clr(void){//清屏函数
lcm_w_test(0,0x01);
}
/******************************************************************************/
voidlcm_clr2(void){//清屏上面3行(用空格填满要清显示的地方,因为液晶屏是静态显示的,所以这办法常用)
lcm_w_test(0,0x80);//第一行
lcm_w_word("");
//标尺("1234567812345678"应该能够显示满一行)
lcm_w_test(0,0x90);//第二行
lcm_w_word("");
//标尺("1234567812345678"应该能够显示满一行)
lcm_w_test(0,0x88);//第一行
lcm_w_word("");
//标尺("1234567812345678"应该能够显示满一行)
}
/******************************************************************************/
//DS18B20温度传感器驱动(显示0至60度,小数点后显示一位)
/******************************************************************************/
voidDelay(intnum){//延时函数
while(num--);
}
/******************************************************************************/
voidInit_DS18B20(void){//初始化ds1820
unsignedcharx=0;
DQ=1;//DQ复位
Delay(8);//稍做延时
DQ=0;//单片机将DQ拉低
Delay(80);//精确延时大于480us
DQ=1;//拉高总线
Delay(14);
x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
Delay(20);
}
/******************************************************************************/
unsignedcharReadOneChar(void){//读一个字节
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--){
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
Delay(4);
}
return(dat);
}
/******************************************************************************/
voidWriteOneChar(unsignedchardat){//写一个字节
unsignedchari=0;
for(i=8;i>0;i--){
DQ=0;
DQ=dat&0x01;
Delay(5);
DQ=1;
dat>>=1;
}
}
/******************************************************************************/
unsignedintReadTemperature(void){//读取温度,温度值返回到此函数中,供调用
unsignedchara=0;
unsignedcharb=0;
unsignedintt=0;
floattt=0;
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0x44);//启动温度转换
Init_DS18B20();
WriteOneChar(0xCC);//跳过读序号列号的操作
WriteOneChar(0xBE);//读取温度寄存器
a=ReadOneChar();//读低8位
b=ReadOneChar();//读高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t=tt*10+0.5;//放大10倍输出并四舍五入
return(t);//t内的温度值,返回到子函数中,要将温度传输到temp变量,应用temp=ReabTemperature()
}
/*****************************************************************************/
//后面会出现的函数声明(当各函数的排列适当时可不用声明,加入函数声明就不用管各个子函数出现的位置先后了?
)
voidlcm_w_ss(void);//向液晶LCM中写秒数据
voidlcm_w_mm(void);//向液晶LCM中写分数据
voidlcm_w_hh(void);//向液晶LCM中写小时数据
voidlcm_w_dd(void);//写日数据
voidlcm_w_mo(void);//写月数据
voidlcm_w_yy(void);//写年数据
voidlcm_w_xq(void);//星期处理并送入LCM的指定区域
unsignedcharclock_in(void);//DS1302逐位写入字节(底层协议)
voidclock_out(unsignedchardd);//1302驱动程序逐位读出字节(底层协议?
voidInit_1302(void);//-设置1302的初始时间(2007年1月1日00时00分00秒星期一)
unsignedcharread_clock(unsignedcharord);//DS1302读数据(底层协议)
voidread_clockS(void);
voidSet_time(unsignedcharsel);//根据选择调整的相应项目sel加1并写入DS1302
voidwrite_clock(unsignedcharord,unsignedchardd);//DS1302写数据(底层协议)
voidupdata(void);
voidlcm_w_nl(void);//显示农历子函数
voidConversion(bitc,unsignedcharyear,unsignedcharmonth,unsignedcharday);//农历年月日计算子函数
voidConver_week(bitc,unsignedcharyear,unsignedcharmonth,unsignedcharday);//星期计算子函数
voidds_w(void);
/*****************************************************************************/
//设置1302的初始时间(自动初始化)
voidInit_1302(void){//-设置1302的初始时间(2007年1月1日00时00分00秒星期一)
unsignedcharf;
if(read_clock(0xc1)!
=0xaa){
write_clock(0x8e,0x00);//允许写操作
write_clock(0x8c,0x07);//年
write_clock(0x8a,0x01);//星期
write_clock(0x88,0x01);//月
write_clock(0x86,0x01);//日
write_clock(0x84,0x00);//小时
write_clock(0x82,0x00);//分钟
write_clock(0x80,0x00);//秒
write_clock(0x90,0xa5);//充电
write_clock(0xc0,0xaa);//写入初始化标志RAM(第00个RAM位置)
for(f=0;f<60;f=f+2){//清除闹钟RAM位为0
write_clock(0xc2+f,0x00);
}
write_clock(0x8e,0x80);//禁止写操作
}
}
/*****************************************************************************/
//DS1302写数据(底层协议)
voidwrite_clock(unsignedcharord,unsignedchardd){
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
clock_out(ord);
clock_out(dd);
clock_Rst=0;
clock_clk=1;
}
/*****************************************************************************/
//1302驱动程序逐位读出字节(底层协议)
voidclock_out(unsignedchardd){
ACC=dd;
clock_dat=a0;clock_clk=1;clock_clk=0;
clock_dat=a1;clock_clk=1;clock_clk=0;
clock_dat=a2;clock_clk=1;clock_clk=0;
clock_dat=a3;clock_clk=1;clock_clk=0;
clock_dat=a4;clock_clk=1;clock_clk=0;
clock_dat=a5;clock_clk=1;clock_clk=0;
clock_dat=a6;clock_clk=1;clock_clk=0;
clock_dat=a7;clock_clk=1;clock_clk=0;
}
/*****************************************************************************/
//DS1302逐位写入字节(底层协议)
unsignedcharclock_in(void){
clock_dat=1;
a0=clock_dat;
clock_clk=1;clock_clk=0;a1=clock_dat;
clock_clk=1;clock_clk=0;a2=clock_dat;
clock_clk=1;clock_clk=0;a3=clock_dat;
clock_clk=1;clock_clk=0;a4=clock_dat;
clock_clk=1;clock_clk=0;a5=clock_dat;
clock_clk=1;clock_clk=0;a6=clock_dat;
clock_clk=1;clock_clk=0;a7=clock_dat;
return(ACC);
}
/*****************************************************************************/
//DS1302读数据(底层协议)供调用时钟数据
unsignedcharread_clock(unsignedcharord){
unsignedchardd=0;
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
clock_out(ord);
dd=clock_in();
clock_Rst=0;
clock_clk=1;
return(dd);
}
/*****************************************************************************/
//扬声器驱动程序(闹钟音乐)
/*****************************************************************************/
voidBeep(void){//BELL-扬声器--整点报时
unsignedchara;//定义变量用于发声的长度设置
for(a=60;a>0;a--){//第一个声音的长度
beep=~beep;//取反扬声器驱动口,以产生音频
Delay(100);//音调设置延时
}
for(a=100;a>0;a--){//同上
beep=~beep;
Delay(80);//
}
for(a=100;a>0;a--){//