/*-------------------------------头文件---------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "DS1302.h"
#include "DS18B20.h"
#include "nongli.h"
#include "displaytime.h"
//#include "jieqi.h"
#define uint unsigned int
#define uchar unsigned char
/*----------------------------定义按键---------------------------------------*/
sbit K1 = P2^3; //K1-设置
sbit K2 = P2^2; //K2-确认、返回
sbit K3 = P2^1; //K3-加
sbit K4 = P2^0; //K4-减
//sbit K5 = P3^7; //液晶背光控制按键,按一下亮,再按一下灭
//sbit BLK = P3^7; //液晶背光控制输出,低电平有效,PNP三极管控制。
/*---------------------函数声明------------------------------*/
void DelayM(uint);
void ds_w(void);
void Conver_week(bit c,uchar year,uchar month,uchar day);
/*-----------------------------定义全局变量------------------------------*/
bit q=0, w=0; //调时标志位
unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
signed char address,item,max,mini;
/*-----------------------------延时函数 1MS/次-------------------------------*/
void DelayM(uint a)
{
uchar i;
while( --a != 0) { for(i = 0; i < 125; i++); }
}
/*-----------------------------日期、时间设置函数-----------------------------*/
void tiaozheng(void){
yy = read_clock(0x8d);//调用1302时钟数据中的年数据,从地址0x8d中
mo = read_clock(0x89);//调用1302时钟数据中的月数据,从地址0x89中
dd = read_clock(0x87);//从1302芯片中读取日数据,从地址0x87中
week = read_clock(0x8b);//从1302芯片中读取星期数据,从地址0x8b中
lcm_w_test(0,0x80);
lcm_w_word("20");//显示内容字符20
write_data(yy/16+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示
write_data(yy%16+0x30);//函数?
lcm_w_word("年");
write_data(mo/16+0x30);
write_data(mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
lcm_w_word("月"); //调用字符显示函数,显示文字 月
write_data(dd/16+0x30);
write_data(dd%16+0x30);//第一个1参数,表示本行写数据,日数据与16取余得个位数,加0x30得到显示码
lcm_w_word("日");//显示字符 日
if(read_clock(0x85) != hh){ //如果程序中的小时与1302芯片中的不同,
hh = read_clock(0x85); //刷新程序中的小时数据
}
lcm_w_test(0,0x91);//第一个参数0,表示本行写入LCM的是指令,指定显示位置91H(第三行左端)
write_data(hh/16+0x30); //显示十位
write_data(hh%16+0x30); //显示个位
lcm_w_word("时");
if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等
mm = read_clock(0x83);//刷新程序中的分钟数据
}
write_data(mm/16+0x30);//向液晶写数据,显示分钟的十位数
write_data(mm%16+0x30);//向液晶写数据,显示分钟的个位数
lcm_w_word("分");
if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等
ss = read_clock(0x81);//刷新程序中的秒钟数据
}
write_data(ss/16+0x30);//向液晶写数据,显示分钟的十位数
write_data(ss%16+0x30);//向液晶写数据,显示分钟的个位数
lcm_w_word("秒");
}
/**********************************************************************************************************/
//调整时间子函数,设置键、数据范围、上调加一,下调减一功能。
void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数
write_com(0x30); write_com(0x06);
lcm_w_test(0,0x98);//第一参数0表示本行写入指令,指定下面行的 调整 显示起始位置为98H
lcm_w_word("★调整");//调用字符显示函数,显示 调整字样
/* if(sel==6) {lcm_w_word("星期");address=0x8a; max=7;mini=1;
tiaozheng();
ds_w();
tiaozheng();
}
*/
//////////////////////////////////////////////////////////////
if(sel==5) {lcm_w_word("秒钟");address=0x80; max=59;mini=0;
tiaozheng(); //调用日期、时间调整函数
ds_w(); //被调数据加一或减一函数
tiaozheng();
} //秒7,按动7次显示 调整秒钟
//并指定秒钟数据写入1302芯片的地址是0x82,秒钟数据的最大值是59,最小值是0
/////////////////////////////////////////////////////////////////////////
if(sel==4) {lcm_w_word("分钟");address=0x82; max=59;mini=0;
tiaozheng();
ds_w();
tiaozheng();
} //分钟6,按动6次显示 调整分钟
//并指定分钟数据写入1302芯片的地址是0x82,分钟数据的最大值是59,最小值是0
if(sel==3) {lcm_w_word("小时");address=0x84; max=23;mini=0;
/***********************************************************/
if(address > 12){
address = address-12; }
/********************************************************/
tiaozheng();
ds_w();
tiaozheng();
} //小时5,按动5次显示 调整小时
//规定小时数据写入1302芯片的位置是0x84,小时数据最大值23,最小值是0
if(sel==2) {lcm_w_word("日期");
address=0x86;
mo = read_clock(0x89);//读月数据
moontemp1=mo/16;
moontemp2=mo%16;
mo=moontemp1*10+moontemp2;//转换成10进制月份数据
yy = read_clock(0x8d);//读年数据
moontemp1=yy/16;
moontemp2=yy%16;
yy=moontemp1*10+moontemp2;//转换成10进制年份数据
if(mo==2&&yy%4!=0){max=28;mini=1;}//平年2月28天
if(mo==2&&yy%4==0){max=29;mini=1;}//闰年2月29天
if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;mini=1;}//31天的月份
if(mo==4||mo==6||mo==9||mo==11){max=30;mini=1;}//30天的月份
tiaozheng();
ds_w();
tiaozheng(); //调用日期、时间调整函数
} //日3,按动3次显示 调整日期
//规定日期数据写入1302的位置地址是0x86,日期最大值31,最小值是1
if(sel==1) {lcm_w_word("月份");address=0x88; max=12;mini=1;
tiaozheng();
ds_w();
tiaozheng();
} //月2,按动2次显示 调整月份
//规定月份写入1302的位置地址是0x88,月份最大值12,最小值1
if(sel==0) {lcm_w_word("年份");address=0x8c; max=99; mini=0;
tiaozheng();
ds_w(); //被调数据加一或减一函数
tiaozheng(); //调用日期、时间调整函数
} //年1,按动1次显示 调整年份,
//规定年份写入1302的地址是0x8c,年份的最大值99,最小值0
}
/*****************************************************************************/
//被调数据加一或减一,并检查数据范围,写入1302指定地址保存
void ds_w(void){
item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;
if(K3 == 0){ //如果按动上调键
item++; //数加 1
}
if(K4 == 0){ //如果按动下调键
item--; //数减 1
}
if(item>max) item=mini;//查看数值是否在有效范围之内
if(item<mini) item=max;//如果数值小于最小值,则自动等于最大值
write_clock(0x8e,0x00);//允许写1302芯片操作
write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
write_clock(0x8e,0x80);//写保护,禁止写操作
}
/****可参考***********可参考**************可参考***************以上是调试********
/*主函数---------------------------------------------------------------------*/
void main()
{
uchar e=0;
K1=1;K2=1;K3=1;K4=1;//BLK=0;//K5=1;
Init_1302(); //时钟芯片初始化
lcm_init(); //液晶初始化
welcome(); //调用欢迎信息
DelayM(4000); //欢迎信息 延时时间
lcm_clr(); //清屏
Clean_12864_GDRAM(); //清屏
while(1)
{
if (w == 0) //正常走时
{
displaydate(); //显示日期
// displaynl(); //显示农历
nongli(); //显示农历
// displayjieqi(); //显示节气
displaytime(); //显示时间
read_temp(); //读取温度
ds1820disp(); //显示温度
displayxq(); //显示星期
}
else {} //否则启动调时
/*----------------------------设置时间--------------------------------------*/
if (K1 == 0)
{
DelayM(20); //按键消抖
if(K1 == 0 && w == 1) //当是调时状态 本键用于调整下一项
{
e++;
if (e >= 7 ) {e = 0;}
while(! K1 ); //等待键松开
Set_time(e); //调整
}
if(K1 == 0 && w == 0) //当是正常状态时就进入调时状态
{
lcm_clr();
Clean_12864_GDRAM(); //清屏
w=1; //进入调时
Set_time(e);
}
while(K1 == 0); //等待键松开
}
/*--------------------------------------------------------------------------*/
if (K2 == 0) // 当在调时状态时就退出调时
{
DelayM(20);
if(K2 == 0 && w == 1)
{
w = 0; //退出调时
e = 0; //"下一项"计数器清0
}
if(K2 == 0 && w == 0)
{
lcm_clr(); Clean_12864_GDRAM();
write_com(0x30); write_com(0x06);
welcome();
while(K2 == 0);
}
lcm_clr(); Clean_12864_GDRAM();
displaydate();
displayxq();
displaynl();
displaytime();
read_temp();
ds1820disp();
while(K2 == 0);
}
/*加调整--------------------------------------------------------------------*/
if (K3 == 0 && w == 1)
{
DelayM(20);
if(K3 == 0 && w == 1) { Set_time(e); }
while(K3 == 0);
while(! K3 );
}
/*减调整--------------------------------------------------------------------*/
if (K4 == 0 && w == 1)
{
DelayM(20);
if(K4 == 0 && w == 1) { Set_time(e); }
while(K4 == 0);
while(! K4 );
}
/*液晶背光控制,按一下亮,再按一下灭----------------------------------------*/
/* if(K5 == 0)
{
DelayM(20); q = ~q; //标志位取反
if(q){BLK = BLK | 1;}
else {BLK = BLK & 0;}
while(K5 == 0);
} */
}
}
/*结束----------------------------------------------------------------------*/