|
话不多说自己看
QQ同V:1137035271
#include <reg52.h>
#include <intrins.h>
#include "LCD12864.h"
#include "DS1302.h"
#include "DS18B20.h"
#include "nongli.h"
#include "displaytime.h"
#include "zk.h"
#include "bell.h"
#include "HW.H"
#include "delay.h"
#define uint unsigned int
#define uchar unsigned char
/*--------------------定义按键-----------------------------------------------*/
sbit K1 = P2^1; //K1-设置
sbit K2 = P2^0; //K2-确认、返回
sbit K3 = P3^7; //K3-加
sbit K4 = P3^6; //K4-减
//K5=P1^4,K5-控制闹钟的打开与关闭,在"hw.h"中定义
/*---------------------函数声明------------------------------*/
void ds_w0(void);
void ds_w(void);
void Conver_week(bit c,uchar year,uchar month,uchar day);
/*-----------------------------定义全局变量------------------------------*/
bit w=0; //调时标志位
unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
signed char address,item,item0,max,mini;
unsigned char clk_ala[2]={0x00,0x00};//闹钟数据存放初,始值为00:00
unsigned char hour,minute,time;//用于闹铃的设置
/*-----------------------------日期、时间设置函数-----------------------------*/
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
lcm_w_test(1,(yy/16)+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示
lcm_w_test(1,yy%16+0x30);//函数
lcm_w_word("年");
//----------------------------------
lcm_w_test(1,(mo/16)+0x30);
lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
lcm_w_word("月");//调用字符显示函数,显示文字 月
//----------------------------------
/*
lcm_w_test(0,0x88);//第一个参数0,表示本行写入LCM的是指令,指定显示位置88H(第三行左端)
lcm_w_word("星期");//调用字符显示函数,显示文字 星期
lcm_w_test(1,mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
*/
//----------------------------------
lcm_w_test(1,(dd/16)+0x30);
lcm_w_test(1,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的是指令,指定显示位置88H(第三行左端)
lcm_w_test(1,(hh/16)+0x30);//显示十位
lcm_w_test(1,hh%16+0x30);//显示个位
lcm_w_word("时");
//----------------------------------
if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等
mm = read_clock(0x83);//刷新程序中的分钟数据
}
lcm_w_test(1,(mm/16)+0x30);//向液晶写数据,显示分钟的十位数
lcm_w_test(1,mm%16+0x30);//向液晶写数据,显示分钟的个位数
lcm_w_word("分");
//----------------------------------
if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等(0x81为读秒数据0x80为写秒数据)
ss = read_clock(0x81);//刷新程序中的秒钟数据
}
lcm_w_test(1,(ss/16)+0x30);//向液晶写数据,显示分钟的十位数
lcm_w_test(1,ss%16+0x30);//向液晶写数据,显示分钟的个位数
lcm_w_word("秒");
//////////////////////////////////////////////////////////////////////
//=========显示闹钟的设置时间===================
hour=clk_ala[0]; //取出上一次的闹钟小时值
minute=clk_ala[1]; //取出上一次的闹钟分钟值
lcm_w_test(0,0x88);
lcm_w_word("闹钟---");
//----------------------------
lcm_w_test(1,(hour/10)+0x30);//显示小时十位
lcm_w_test(1,(hour%10)+0x30);//显示小时个位
//----------------------------
lcm_w_word(":");
//----------------------------
lcm_w_test(1,(minute/10)+0x30);//显示分钟的十位
lcm_w_test(1,(minute%10)+0x30);//显示分钟的个位
//----------------------------
lcm_w_word("----");
/////////////////////////////////////////////////////////////////////////
}
/*****************************************************************************/
//被调数据加一或减一,并检查数据范围,写入1302指定地址保存
void ds_w(void)
{
item0=time;
item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;//时间的调整
if(K3 == 0||key_add==1){//如果按动上调键
item++;//数加 1
}
if(K4 == 0||key_minish==1){//如果按动下调键
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 ds_w0(void)
{
item0=time;
if(K3 == 0||key_add==1){//如果按动上调键
item0++;//数加 1
}
if(K4 == 0||key_minish==1){//如果按动下调键
item0--;//数减 1
}
if(item0>max) item0=mini;//查看数值是否在有效范围之内
if(item0<mini)item0=max;//如果数值小于最小值,则自动等于最大值
time=item0;//调整后的时间重新赋值给time(time为hour或minute),这步很重要,没有将无法更新闹钟数据
}
/**********************************************************************************************************/
//调整时间子函数,设置键、数据范围、上调加一,下调减一功能。
void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数
write_com(0x30); write_com(0x06);
lcm_w_test(0,0x98);//第一参数0表示本行写入指令,指定下面行的 调整 显示起始位置为9AH
lcm_w_word(">>调整>> <<<<");//调用字符显示函数,显示 调整字样
/* if(sel==8) {lcm_w_word("星期");address=0x8a; max=7;mini=1;
tiaozheng();
ds_w();
tiaozheng();
}
*/
//================================================================
lcm_w_test(0,0x9c);
if(sel==7) {lcm_w_word("闹钟分"); time=minute;max=59;mini=0;
tiaozheng();//显示调整前的内容
ds_w0();//设置闹钟
clk_ala[1]=time;//把更新后的分钟数据重新保存
tiaozheng();//显示调整后的内容
}//按动8次显示 调整闹钟的分钟部分
if(sel==6) {lcm_w_word("闹钟时");time=hour; max=23;mini=0;
tiaozheng();
ds_w0();
clk_ala[0]=time;//把更新后的小时数据重新保存
tiaozheng();
}//按动7次显示 调整闹钟的小时部分
//================================================================
if(sel==5) {lcm_w_word("秒钟");address=0x80; max=59;mini=0;
tiaozheng(); //调用日期、时间调整函数
ds_w(); //被调数据加一或减一函数
tiaozheng();
} //秒6,按动6次显示 调整秒钟
//并指定秒钟数据写入1302芯片的写入地址是0x80,秒钟数据的最大值是59,最小值是0
if(sel==4) {lcm_w_word("分钟");address=0x82; max=59;mini=0;
tiaozheng();
ds_w();
tiaozheng();
} //分钟5,按动5次显示 调整分钟
//并指定分钟数据写入1302芯片的地址是0x82,分钟数据的最大值是59,最小值是0
if(sel==3) {lcm_w_word("小时");address=0x84; max=23;mini=0;
tiaozheng();
ds_w();
tiaozheng();
} //小时4,按动4次显示 调整小时
//规定小时数据写入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
}
/*********************************************************************
**********************************************************************
************** 主函数 ****************
**********************************************************************
/********************************************************************/
void main()
{
unsigned char e=0,f=0,tmp,i;
IE = 0x81; //允许总中断中断,使能 INT0 外部中断
TCON = 0x01; //触发方式为脉冲负边沿触发
IRIN=1; //IO口初始化
BEEP=1;
K1=1;K2=1;K3=1;K4=1;
Init_1302(); //时钟芯片初始化
lcm_init(); //液晶初始化
welcome0(); //调用欢迎信息1
DelayM(2000);//延时
//welcome();DelayM(1000); //调用欢迎信息2
lcm_clr(); //清屏
Clean_12864_GDRAM(); //清屏
while(1)
{
if (w == 0) //正常走时
{
displaydate(); //显示日期
displaynl(); //显示农历
displaytime(); //显示时间
read_temp(); //读取温度
ds1820disp(); //显示温度
displayxq(); //显示星期
//=================以下是闹钟的相关处理===================
if(ala_flag==1){//闹钟标志位
set1616pic(6,1,0,2);} //显示"闹钟图标"
else{
set1616pic(6,1,0,3);}//关闭"闹钟图标"显示
//----------------------------------------
tmp=read_clock(0x85);//取出1302小时
i = tmp/16;
tmp = tmp&0x0f;
tmp = tmp + i*10;
if(clk_ala[0]==tmp)//与闹钟设定的小时值相同
{
tmp=read_clock(0x83);//取出1302分钟
i = tmp/16;
tmp = tmp&0x0f;
tmp = tmp + i*10;
if(clk_ala[1]==tmp)//与闹钟设定的分钟值相同
{
if(ala_flag==1)//闹钟打开
{
alarmbeep();//闹铃声响1分钟后自动关闭,
DelayM(200);//控制闹钟响的间隔即频率
}
else BEEP=1;//关闭蜂鸣器
}
else BEEP=1;//关闭蜂鸣器
}
//==============闹钟处理结束=======================
}
else {} //========否则启动调时=========================
/*---------------按键及红外遥控设置时间------------------------------*/
if (K1 == 0||key_manue==1)
{
DelayM(8); //按键消抖
/*当是调时状态 本键用于调整下一项---------------------------------------------------*/
if((K1 == 0 && w == 1)||(key_manue==1&&w==1)) //
{
e++;
if (e >= 8 ) {e = 0;}
while(! K1 ); //等待键松开
key_manue=0;
Set_time(e); beep(); //调整
}
/*当是正常状态时就进入调时状态---------------------------------------------------*/
if((K1 == 0 && w == 0)||(key_manue==1&&w==0)) //
{
key_manue=0;
lcm_clr();
Clean_12864_GDRAM(); //清屏
w=1; //进入调时
Set_time(e);beep();
}
while(K1 == 0); //等待键松开
}
/*当在调时状态时就退出调时---------------------------------------------------*/
if (K2 == 0||key_ok==1) //
{ beep();
DelayM(8);
if((K2 == 0 && w == 1)||(key_ok==1&&w==1))
{
w = 0; //退出调时
e = 0; //"下一项"计数器清0
}
if((K2 == 0 && w == 0)||(key_ok==1&&w==0))
{
lcm_clr(); Clean_12864_GDRAM();
write_com(0x30); write_com(0x06);
welcome();
while(K2 == 0); //按下K2是显示欢迎信息
DelayM(500);key_ok=0;//红外"OK"按键按下时显示0.5秒钟的欢迎界面2
}
lcm_clr(); Clean_12864_GDRAM();
// ds_write(0x0a,0x20); //调时完毕,开启时钟振荡器
displaydate();
displayxq();
displaynl();
displaytime();
read_temp();
ds1820disp();
while(K2 == 0);
}
/*加调整--------------------------------------------------------------------*/
if ((K3 == 0 && w == 1)||(key_add==1&&w==1))
{
DelayM(8);
if((K3 == 0 && w == 1)||(key_add==1&&w==1))
{
Set_time(e);
beep();
while(!K3);
key_add=0;
}
key_add=0;
while(! K3 );
}
/*减调整--------------------------------------------------------------------*/
if ((K4 == 0 && w == 1)||(key_minish==1&&w==1))
{
DelayM(10);
if((K4 == 0 && w == 1)||(key_minish==1&&w==1))
{
Set_time(e);
beep();
while(! K4 );
key_minish=0;
}
key_minish=0;
while(! K4 );
}
/*----------------------------------------------------------------*/
}
}
|
|