本文共 11292 字,大约阅读时间需要 37 分钟。
/*---------------------------------------------------------------------------
电子时钟程序
单 片 机:STC89C58RC
晶 振:12MHz
时钟芯片:DS1302
液 晶 屏:LCM-12864-ST7920
功能描述: 大数字显示时间;能显示农历、设置闹铃;
说 明:LCM12864使用并口连接方式,PSB、RST接高电平
------------------------------------------------------------------------------*/
/*-------------------------------头文件---------------------------------------*/
#include
#include
#include "LCD12864.h"
#include "DS1302.h"
#include "nongli.h"
#include "displaytime.h"
#include "zk.h"
#include "bell.h"
#include "HW.H"
#include "delay.h"
#include "DS18B20.h"
#define uint unsigned int
#define uchar unsigned char
/*--------------------定义按键-----------------------------------------------*/
sbit K1 = P2^3; //K1-设置
sbit K2 = P2^4; //K2-确认、返回
sbit K3 = P2^5; //K3-加
sbit K4 = P2^6; //K4-减
sbit K5 = P2^7; //K5-控制闹钟的打开与关闭,在"hw.h"中定义
sbit K6 = P2^2; //背光控制
sbit LED = P2^0; //背光灯
/*---------------------函数声明------------------------------*/
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]={0x05,0x2f};//闹钟数据存放初,始值为05:27
unsigned char zwc=0,fwc=0,CKTIME_1=0,timp,timp0,timp1,timp2,hhh,mmm,sss;//用于校时
unsigned char hour=0,minute=0,time=0;//用于闹铃的设置
unsigned char gCount;
/*-----------------------------调整界面设置函数-----------------------------*/
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");
lcm_w_test(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);
lcm_w_word("-");
//----------------------------------
lcm_w_test(1,(dd/16)+0x30);
lcm_w_test(1,dd%16+0x30);
//----------------------------------
if(read_clock(0x85) != hh){hh = read_clock(0x85);}
lcm_w_test(0,0x88);
lcm_w_test(1,(hh/16)+0x30);
lcm_w_test(1,hh%16+0x30);
lcm_w_word(":");
//----------------------------------
if(read_clock(0x83) != mm){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){ss = read_clock(0x81);}
lcm_w_test(1,(ss/16)+0x30);
lcm_w_test(1,ss%16+0x30);
//=========显示设置闹钟的时间===================
if(read_clock(0xc7) != hour){hour = read_clock(0xc7);}
if(read_clock(0xc9) != minute){minute = read_clock(0xc9);}
lcm_w_test(0,0x8d);
lcm_w_test(1,(hour/16)+0x30);//显示闹钟小时十位
lcm_w_test(1,(hour%16)+0x30);//显示闹钟小时个位
lcm_w_word(":");
lcm_w_test(1,(minute/16)+0x30);//显示闹钟分钟的十位
lcm_w_test(1,(minute%16)+0x30);//显示闹钟分钟的个位
//=========显示设置时间校正===================
if(read_clock(0xc5) != zwc){zwc = read_clock(0xc5);} //加减标志
if(read_clock(0xc3) != fwc){fwc = read_clock(0xc3);} //调整多少秒
lcm_w_test(0,0x90);
lcm_w_word("每天零点时");
lcm_w_test(0,0x95);
if(zwc==0){lcm_w_word("加");}
if(zwc==1){lcm_w_word("减");}
lcm_w_test(0,0x96);
lcm_w_test(1,(fwc/16)+0x30);
lcm_w_test(1,(fwc%16)+0x30);
lcm_w_test(0,0x97);
lcm_w_word("秒");
}
void displayNaozh() //闹钟显示
{
if(read_clock(0xc7) != hour){
hour = read_clock(0xc7);
}
if(read_clock(0xc9) != minute){
minute = read_clock(0xc9);
}
lcm_w_test(0,0x85);
lcm_w_test(1,(hour/16)+0x30);//显示小时十位
lcm_w_test(1,(hour%16)+0x30);//显示小时个位
lcm_w_word(":");
lcm_w_test(1,(minute/16)+0x30);//显示分钟的十位
lcm_w_test(1,(minute%16)+0x30);//显示分钟的个位
lcm_w_word(" ");
}
void ds_w(void) //被调数据加一或减一,并检查数据范围,写入1302指定地址保存
{
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
write_clock(0x8e,0x00);//允许写1302芯片操作
write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
write_clock(0x8e,0x80);//写保护,禁止写操作
time=item0;//调整后的时间重新赋值给time(Tt为Hh或Mm),这步很重要,没有将无法更新闹钟数据
}
/**********************************************************************************************************/
void Set_time(unsigned char sel){
//根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数
write_com(0x30); write_com(0x06);
lcm_w_test(0,0x98);
lcm_w_word("调整>");//调用字符显示函数,显示 调整字样
//================================================================
lcm_w_test(0,0x9c);
if(sel==9) {lcm_w_word("调整多少");address=0xc2; max=29;mini=0;
tiaozheng();
ds_w();
tiaozheng();
} //按动10次显示 调整多少秒
if(sel==8) {lcm_w_word("加减调整");address=0xc4;max=1;mini=0;
tiaozheng(); //显示调整前的内容
ds_w(); //设置闹钟
tiaozheng(); //显示调整后的内容
} //按动9次显示 快还是慢
//================================================================
lcm_w_test(0,0x9c);
if(sel==7) {lcm_w_word("闹钟分钟");address=0xc8;max=59;mini=0; //数据写入1302芯片的写入地址是0xc8,最大值是59,最小值是0
tiaozheng(); //显示调整前的内容
ds_w(); //设置闹钟
tiaozheng(); //显示调整后的内容
} //按动8次显示 调整闹钟的分钟部分
if(sel==6) {lcm_w_word("闹钟小时");address=0xc6; max=23;mini=0;
tiaozheng();
ds_w();
tiaozheng();
} //按动7次显示 调整闹钟的小时部分
//================================================================
if(sel==5) {lcm_w_word("调整秒钟");address=0x80; max=59;mini=0;
tiaozheng();
ds_w();
tiaozheng();
}
if(sel==4) {lcm_w_word("调整分钟");address=0x82; max=59;mini=0;
tiaozheng();
ds_w();
tiaozheng();
}
if(sel==3) {lcm_w_word("调整小时");address=0x84; max=23;mini=0;
tiaozheng();
ds_w();
tiaozheng();
}
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();
}
if(sel==1) {lcm_w_word("调整月份");address=0x88; max=12;mini=1;
tiaozheng();
ds_w();
tiaozheng();
}
if(sel==0) {lcm_w_word("调整年份");address=0x8c; max=99; mini=0;
tiaozheng();
ds_w();
tiaozheng();
}
}
//------------------------------------------------------
void BiasAmend() //时间修正函数
{
hhh = (read_clock(0x85)/16)*10+read_clock(0x85)%16;
mmm = (read_clock(0x83)/16)*10+read_clock(0x83)%16;
sss = (read_clock(0x81)/16)*10+read_clock(0x81)%16;
timp0= 30+((fwc/16)*10+fwc%16);
timp= 30-((fwc/16)*10+fwc%16);
if((hhh==0)&&(mmm==1)&&(sss==0)){CKTIME_1=0;}
if((hhh==0)&&(mmm==0)&&(sss==30)&&CKTIME_1==0)
{
if( zwc==0) //加调整
{
write_clock(0x8e,0x00); //允许写操作
write_clock(0x80,(timp0/10)*16+timp0%10); //对秒进行调整。
write_clock(0x8e,0x80); //禁止写操作
CKTIME_1=1; //保证只调整一次
}
if( zwc==1) //减调整
{
write_clock(0x8e,0x00); //允许写操作
write_clock(0x80,(timp/10)*16+timp%10); //对秒进行调整
write_clock(0x8e,0x80); //禁止写操作
CKTIME_1=1; //保证只调整一次
}
}
}
// -----------------------------------------------------
void naozbiaoz() //闹钟标志函数
{
if(read_clock(0xcb) != ala_flag){ala_flag = read_clock(0xcb);} //闹钟标志
if(ala_flag==1) //闹钟标志位
{set1616pic(5,1,0,2);} //显示"喇叭"
else
{set1616pic(5,1,0,1);} //关闭"喇叭"显示
}
/*********************************************************************
**********************************************************************
************** 主函数 ****************
**********************************************************************
/********************************************************************/
void main()
{
unsigned char ala_flag=1,e=0,f=0;
IE = 0x81; //允许总中断中断,使能 INT0 外部中断
TCON = 0x01; //触发方式为脉冲负边沿触发
IRIN=1; //IO口初始化
BEEP=1;
K1=1;K2=1;K3=1;K4=1;LED=0;
Init_1302(); //时钟芯片初始化
lcm_init(); //液晶初始化
welcome0(); //调用欢迎信息1
DelayM(1000);//延时
lcm_clr(); //清屏
Clean_12864_GDRAM(); //清屏
while(1)
{
if (w == 0) //正常走时
{
hhh = (read_clock(0x85)/16)*10+read_clock(0x85)%16;
mmm = (read_clock(0x83)/16)*10+read_clock(0x83)%16;
sss = (read_clock(0x81)/16)*10+read_clock(0x81)%16;
clk_ala[0]=(read_clock(0xc7)/16)*10+read_clock(0xc7)%16;
clk_ala[1]=(read_clock(0xc9)/16)*10+read_clock(0xc9)%16;
if ((sss==1)||(sss==2)||(sss==5)||(sss==6)||(sss==9)||(sss==10)||(sss==13)||(sss==14)||(sss==17)||(sss==18)||(sss==21)||(sss==22)||(sss==25)||(sss==26)||(sss==29)||(sss==30)||(sss==33)||(sss==34)||(sss==37)||(sss==38)||(sss==41)||(sss==42)||(sss==45)||(sss==46)||(sss==49)||(sss==50)||(sss==53)||(sss==54)||(sss==57)||(sss==58))
{displaydate(); displayJr(); displayNaozh(); } //显示日期 显示农历 显示闹钟
if ((sss==3)||(sss==4)||(sss==7)||(sss==8)||(sss==11)||(sss==12)||(sss==15)||(sss==16)||(sss==19)||(sss==20)||(sss==23)||(sss==24)||(sss==27)||(sss==28)||(sss==31)||(sss==32)||(sss==35)||(sss==36)||(sss==39)||(sss==40)||(sss==43)||(sss==44)||(sss==47)||(sss==48)||(sss==51)||(sss==52)||(sss==55)||(sss==56)||(sss==59)||(sss==0))
{displaynl(); displayGK();{read_temp(); ds1820disp(); } //显示农历 显示高考 //读取温度 //显示温度
displaytime(); //显示时间
naozbiaoz(); // 闹钟标志
displayxq(); //显示星期
BiasAmend(); //时间校正函数
}
//=================以下是闹钟的相关处理===================
if((clk_ala[0]==hhh)&&(clk_ala[1]==mmm)&&(sss<10)&&(ala_flag==1))
{ alarmbeep();DelayM(200);}
//{ BEEP=0;}
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 >= 10 ) {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();
}
key_manue=0;
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
lcm_clr(); //清屏
Clean_12864_GDRAM(); //清屏
}
}
/*加调整--------------------------------------------------------------------*/
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 );
}
/*----------------------------------------------------------------*/
if(K5 == 0 )//闹钟的开与关的设置标志位
{
DelayM(20);
if(K5 == 0 )
{ beep();
while(!K5);//松手检测
ala_flag=!ala_flag;
if(ala_flag==0)
{
write_clock(0x8e,0x00);//允许写1302芯片操作
write_clock(0xca,0x00);//转换成16进制写入1302
write_clock(0x8e,0x80);//写保护,禁止写操作
}
if(ala_flag==1)
{
write_clock(0x8e,0x00);//允许写1302芯片操作
write_clock(0xca,0x01);//转换成16进制写入1302
write_clock(0x8e,0x80);//写保护,禁止写操作
}
}
while(!K5);//松手检测
key_alarm=0;
}
/*----------------------------------------------------------------*/
if(K6 == 0)
{
DelayM(20);
if(K6 == 0 )
{ beep();
while(!K6);//松手检测
LED=!LED;
gCount = 0;
}
while(!K6);//松手检测
}
}
}
/*结束----------------------------------------------------------------------*/
转载地址:https://blog.csdn.net/weixin_32048757/article/details/117212249 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!