电子闹钟设计

2023-10-26

摘要 本设计是以89c51单片机作为控制核心的闹铃系统。本文大致可以分三个章节,第一章讲用单片机制作电子闹钟带来的优势,还有电子闹钟在未来的电子产品中的趋势以及本次设计所要实现的课题目标。第二章讲一些设计思路和硬件组成。第三讲程序代码,最后结论,体会,附录图。
关键词 pc机,单片机,串行通讯,LCD1602显示。

电了闹钟是一种应用非常广泛的日常计时工具,数字显示的日历钟已经越来越流行,特别是适合在家庭居室、办公室、大厅、会议室、车站和广场等使用,壁挂式LED数码管显示的日历钟逐渐受到人们的欢迎。单片机电了闹钟是集电子技术、数字显示技术为一体的高产品,具有按时闹铃,显示清晰直观、走时准确等优点。首先介绍设计电子闹钟所涉及的主要硬件和特性,然后说明软件设计的思路,程序结构及流程,并在测试软件上进行调试和修改,以完成电子闹钟的基本要求,即可以随意设定起始时间,有秒显示功能,有2/24时制选择,可以设定闹钟,停电时由电池供电等功能。现代社会电了闹钟发挥着很大的作用,也是它存在和发展的一个重要方面,尤其是在代表集成电路技术的发展方面,通过不断提高电子闹钟的计时的精确度可以极大促进定时技术芯片的发展。同时电了闹钟与其他嵌入式电子产品一样是微处理器的应用,通过电子闹钟的设计可以很好的掌握电子设计技术

AT89C51简介
AT89C51是一个低功耗,高性能CMOS8位单片机,片内含4kBytes ISP(In-systemprogrammable)的可反复擦写1佣0次的Flash只读程序存储器,器件采用ATMEL公同的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的AT89C51可为许多嵌入式控制应用系统提供高性价比的解决方案。
引脚介绍
AT89C51具有如下特点:40个引脚,4kBytesFlash片内程序存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出囗,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
在这里插入图片描述
此外,AT89C51设计和配置了振荡频率可为OHz并可通过软件设置省电模式。空闲模式下,CPU暂停工作,血RAM定时计数器,串行凵,外中断系统可继续工作,掉电模式冻结振荡器血保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
主要功能特性:
·兼容MCS-51指令系统
·32个双向1/0囗
·2个16位可编程定时/计数器
·全双工CART串行中断口线
·2个外部中断源
·中断唤醒省电模式
·看门狗(WDT)电路
·灵活的ISP字节和分页编程
·4k可反复擦写01000次)ISPFlashROM
·4.5一5.5V工作电压时钟频率0-33MHz
·128x8bit内部RAM
·低功耗空闲和省电模式
·3级加密位
·软件设置空闲和省电功能
·双数据寄存器指针

设计一个电子闹钟
1) 能随意设定走时起始时间
2) 能指示秒节奏,即秒指示
3) 能通过pc机远程控制
4) 可设闹钟7组(可继续增加)
5) 可以设置重复/不重复(和手机闹钟设置一样)
6) 显示实时温度
7) 可选音乐5首(可继续增加)
1 时间设置
1)ds1302的调试
2)ds18b20的调试
3)ds1302与ds18b20的组合调试
4)/key1: 选择设置位置/
/******key2: 加 ******/
/******key3: 减 ******/
/******key4: 退出设置 ******/
2 闹钟设置
1) 建立一个数组储存闹钟alarm[7][5];
alarm[x][0] 分钟设置,
alarm[x][1] 小时设置,
alarm[x][2] 开关闹钟,
alarm[x][3] 重复/不重复,
alarm[x][4] 选择音乐
2) 建立一个数组储存闹钟重复/不重复repeat[7][7];
repeat[x][0] 星期一 1重复 0不重复
repeat[x][1] 星期二 1重复 0不重复
repeat[x][2] 星期三 1重复 0不重复
repeat[x][3] 星期四 1重复 0不重复
repeat[x][4] 星期五 1重复 0不重复
repeat[x][5] 星期六 1重复 0不重复
repeat[x][6] 星期日 1重复 0不重复
3) 建立一个数组储存闹钟暂停功能stop[7];
stop[x] 1不暂停 0暂停

总体硬件组成
在这里插入图片描述
基本功能
系统具有时间,日期,7路闹钟功能,并可以对时间日期,闹钟进行设定,闹钟有5首音乐可选择,显示格式为:
时间:“时”(第1、2位)、“分”(第3、4位)、“秒”(第5、6位),am/pm(第7位)
日期:“年”(第1、2,3,4位,如2007年)、“月”(第5、6位)、“日”(第7、8位),“周”(第9位)
扩展功能
该系统可以增加温度传感器,实现温度测量,以实时显示温度,用2位显示。
可增加湿度传感器,实现湿度测量,以实时显示湿度,用3位显示。

/****** 主界面显示 /
/2018年01月01日 P 星期五/
/12:01:01 温度:20C 闹钟开关/
在这里插入图片描述
/
主界面按键功能 ******/
/******key1: 进入设置 ******/
/******key2: 加 ******/
/******key3: 减 ******/
/******key4: 打开闹钟 ******/

/****** 功能选择 ******/
/******1:timeSet ******/
/******2: alarmSet /
/ 按键功能 ******/
/******key1: 进入设置 ******/
/******key2: 加 ******/
/******key3: 减 ******/
/******key4: 退出设置 /
在这里插入图片描述
/
时间设置 ******/
/key1: 选择设置位置/
/******key2: 加 ******/
/******key3: 减 ******/
/******key4: 退出设置 /
在这里插入图片描述
/
闹钟设置 /
/ +:增加,-:删除 ******/
/******key1: 确定选择 ******/
/******key2: 选择设置位置加1 ******/
/******key3: 选择设置位置减1 ******/
/******key4: 退出设置 /
在这里插入图片描述
/
闹钟x ******/
/******key1: 选择设置 (时间,开关,重复/不重复,选择音乐)******/
/******key2: 加1 ******/
/******key3: 减一 ******/
/******key4: 退出设置 /
在这里插入图片描述
/
重复/不重复 ******/
/******key2: 重复 ******/
/******key3: 不重复 ******/

/****** 重复 ******/
/key1:选择设置位置/
/******key2: 开启重复 ******/
/******key3: 关闭重复 ******/
/******key4: 退出设置 /
在这里插入图片描述
/
不重复 ******/
/key1:选择设置位置/
/******key2: 开启 ******/
/******key3: 关闭 ******/
/******key4: 退出设置 ******/
时钟电路
实验板的时钟振荡源电路如图2.4所示。其中JT为庄0592MHz的晶振,
改变两电容CB的值即可对此晶振频率进行调节。该电路提供单片机工作所需的
振荡频率,计算定时器初值即需此晶振频率,在通信时也需知道晶振频率,以
对波特率进行计算。
在这里插入图片描述
复位电路
如图2.5所示为实验板的复位电路,当RESET信号为低电平时,实验板为
工作状态,当RESET信号为高电平时,实验板为复位或下载程序状态。由于
AT89S52貝有ISP的功能,即可以通过并口线直接将程序下载到单片机内,因
此,AT89S52具有两种状态,下载程序状态和运行状态。该复位电路能实现上
电自动复位,也能手动复位,一般复位时RESET应保持20毫秒以上高电平,此
复位时间由接地电容控制。
在这里插入图片描述
键盘电路
key1:P1.4
key2:P1.5
key3:P1.6
key4:P1.7
LCD1602显示电路
在这里插入图片描述
数据分配
TIME[7]:秒分时日月周年
alarm[x][0] 分钟设置,
alarm[x][1] 小时设置,
alarm[x][2] 开关闹钟,
alarm[x][3] 重复/不重复,
alarm[x][4] 选择音乐
repeat[x][0] 星期一 1重复 0不重复
repeat[x][1] 星期二 1重复 0不重复
repeat[x][2] 星期三 1重复 0不重复
repeat[x][3] 星期四 1重复 0不重复
repeat[x][4] 星期五 1重复 0不重复
repeat[x][5] 星期六 1重复 0不重复
repeat[x][6] 星期日 1重复 0不重复
stop[x] 1不暂停 0暂停
时钟程序设计步骤
在这里插入图片描述
实现方式
该时钟程序的功能模块先后实现的顺序为.
主程序一时间模块一显示模块一键盘模块一时间设定及其显示模块一日期及其显示模块一日期设定及其显示模块—闹钟设定及其显示模块—闹钟重复设定及其显示模块
每完成一个模块就与前一个已完成的模块结合起来调试,直至实现相应功能,再编写下一模块程序.在与主程序衔接时,主程序和各子程序也需作相应的改动,以便与子程序更好的衔接,特别是显示子程序需作较大改动,以便对不同内容进行显示。
源程序

sys.h
#ifndef __SYS_H
#define __SYS_H
#include "reg51.h"
#include "intrins.h"
#ifndef uchar 
#define uchar unsigned char
#endif
#ifndef uint 
#define uint unsigned int
#endif
#ifndef ulong 
#define ulong unsigned long
#endif
#endif
main.c
#include "sys.h"
#include "delay.h"
#include "lcd1602.h"
#include "temp.h"
#include "ds1302.h"
#include "keyProcess.h"
#include "otherProcess.h"
#include "musicCode.h"
#define RldTmr(fr) 65536 - (11059200 / 12) / (fr << 1)
#define FuDian(n) (n << 1) / 3    //附点n分音符的换算
sbit beep = P2^0;

uchar Temp_TH0,Temp_TL0;
uchar Temp_TH1,Temp_TL1; 
uchar tmrFlg=0,enable = 1;
extern uint mflag;	  //音符计算
extern bit nflag;
extern bit aflag;	  //闹钟开关
extern uchar a;
extern uchar b;

void PlayMusic(uchar *Sound,uchar *lengthlen,uint speed);    //固定标准为4分音符的速度:例如speed = 108 表示一分钟扫过108个4分音符
void sound_Init();
uint length(uchar *Sound);			 //判断音符个数
uint mflag;							 //音符循环个数
bit nflag=0;						 //1分钟关闭闹钟暂停标志
bit aflag=1;	//总开关
uchar stop[5];	//暂停标志位

uchar a;	   //闹钟x
uchar b;	   //重复检测
void main()
{
	uchar mode;	   
	stop[0]=1;	   //暂停标志位
	stop[1]=1;
	stop[2]=1;
	stop[3]=1;
	stop[4]=1;
	Clock=0;	   //初始闹钟个数
	
	LCD1602_Init();	   //1602初始化
	DS1302_Init();	   //1302初始化
	sound_Init();	   //定时器初始化
	
	while(1)
	{	
		/**********按键处理***********/	
		if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)
		{				
			switch (key_scan())
			{	
				case K1: mode=MODE0;break;		//MODE0进入菜单
				case K2: mode=MODE1;break;		//MODE0设置日期
				case K3: mode=MODE2;break;		//MODE0设置闹钟
				case K4: mode=MODE3;aflag=!aflag;break;		//MODE3退出
			}
			key_process(mode);				   //按键处理函数
		}
		/**********主屏幕显示**********/		
		LCD1602_DisplayTemp(DS18B20_ReadTemp());	 //温度
		DS1302_ReadTime();							 //读时间
		LCD1602_DisplayData();						 //显示时间
		if(AM_PM==0&&hour12_24==1)					 //显示上午
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData('A');
		}
		if(AM_PM==1&&hour12_24==1)					 //显示下午
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData('P');
		}											 //24小时制
		if(hour12_24==0)
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData(' ');
		}
		LCD1602_WriteCom(0xc0+15);					 //显示闹钟开关
		if(aflag)
			LCD1602_WriteData('N');
		else 
			LCD1602_WriteData('F');
		/**********闹钟设置**********/
		if(aflag==1)
		{
		for(a=0;a<=Clock;a++)			 //检测闹钟
		{
			if(alarm[a][2]==1)		 //判断闹钟是否开启
			{
				if(alarm[a][3]==1)	  //判断是否重复 alarm[a][3]==1为重复
				{
					for(b=0;b<7;b++)		//判断周是否重复
					{
					 if(TIME[5]==b+1&&repeat[a][b]==1)	  //	repeat[a][0]		  重复天数星期一到星期日
					 {
						 if((alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))	   //alarm[0][0]=分钟 alarm[0][1]=小时	
						{
							nflag=1;
							switch(alarm[a][4])
							{
								case 0:	   PlayMusic(musicNote5,noteDuration5,108);	  break;
								case 1:	   PlayMusic(musicNote1,noteDuration1,108);	  break;
								case 2:	   PlayMusic(musicNote2,noteDuration2,108);	  break;
								case 3:	   PlayMusic(musicNote3,noteDuration3,108);	  break;
								case 4:	   PlayMusic(musicNote4,noteDuration4,108);	  break;
							
							}
					
						}
						else
							stop[a]=1;
					}
					}
				} 
				else
				{
					for(b=0;b<7;b++)
					{
					 if(TIME[5]==b+1&&repeat[a][b]==1)	  //	repeat[a][0]		  重复天数星期一到星期日
					 {
						 if((alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))	   //alarm[0][0]=分钟 alarm[0][1]=小时	
						{
							switch(alarm[a][4])
							{
								case 0:	   PlayMusic(musicNote5,noteDuration5,108);	  break;
								case 1:	   PlayMusic(musicNote1,noteDuration1,108);	  break;
								case 2:	   PlayMusic(musicNote2,noteDuration2,108);	  break;
								case 3:	   PlayMusic(musicNote3,noteDuration3,108);	  break;
								case 4:	   PlayMusic(musicNote4,noteDuration4,108);	  break;
							
							}
					
						}
						else
							stop[a]=1;
					}
					}
				}
		}
		}
		}
		else
		{
			 beep=1;TR0=0;
		}
		LCD1602_WriteCom(0xc0+15);
		if(stop[a]==1)
		{
			LCD1602_WriteData('1');	
		}
		else
			LCD1602_WriteData('0');
		delay_ms(10);
	}

}

/********音乐代码*********/
void sound_Init()
{
	
    Temp_TH1 = (65535-1000)/256; // 计算TL1应装入的初值 (1ms的初装值) 
	Temp_TL1 = (65535-1000)%256; // 计算TH1应装入的初值 
	beep=1;
	EA=1;
	TMOD|=0x11;
	TH1=Temp_TH1;
	TL1=Temp_TL1;
	TH0=0xff;
	TL0=0x00;
	ET0=1;
	ET1=0;
	TR0=0;
	TR1=0;
} 
uint length(uchar *Sound)
{
	uint SoundLength=0;
	while(Sound[SoundLength] != 0) //计算歌曲长度 
	{ 
		SoundLength+=1; 
	} 	
	return SoundLength;
}
void PlayMusic(uchar *Sound,uchar *music,uint speed) {
    uint i;
    uchar idx;
	uint Tone,Temp_T,durationCnt=0,soundCnt=0,NO_soundCnt=0,cnt=0;

	TR0 = 1; 
	TR1 = 1; 
	Tone=length( Sound);
	mflag=0;
	if((alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))
		nflag=1;
	else
	{
		nflag=0;
		if(alarm[a][3]==0)
			repeat[a][b]=0;
	}
	while(mflag!=Tone&&nflag==1&&stop[a]==1)
	{
		if((alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))
			nflag=1;
		else
		{
			nflag=0;
			stop[a]=1;
			if(alarm[a][3]==0)
				repeat[a][b]=0;
		}
		if(nflag==0)
		{	TR0=0;
			break;
		}
		if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)
		{				
			switch (key_scan())
			{
				case K1: break;
				case K2: break;
				case K3: break;
				case K4: stop[a]=0;delay_ms(100);
						 if(alarm[a][3]==0)
							repeat[a][b]=0;
						 break;
			}
		}
       	while (!tmrFlg) ;
        tmrFlg = 0;
            idx = Sound[mflag] - 1;
	  		Temp_T=	tmrRld[idx];
            Temp_TH0 = Temp_T/256; 
			Temp_TL0 = Temp_T%256; 
			TH0 = Temp_TH0; 
			TL0 = Temp_TL0 + 12; //加12是对中断延时的补偿
			durationCnt = (ulong)240 * (ulong)noteFreq[idx] / ((ulong)music[mflag] * (ulong)speed);
			soundCnt=durationCnt-(durationCnt >> 2);//发声
            NO_soundCnt =  durationCnt >> 2;	//当前音符时值的前3/4发声,后1/4静音
			for(i=soundCnt;i>0;i--) //发规定长度的音 
			{ 
				while(TF1==0); 
				TH1 = Temp_TH1; 
				TL1 = Temp_TL1; 
				TF1=0; 				
			}  
 			enable=0;
			for(i=NO_soundCnt-20;i>0;i--) //音符间的间隔 
			{ 
				while(TF1==0); 
				TH1 = Temp_TH1; 
				TL1 = Temp_TL1+50; 
				TF1=0; 
			}
		if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)
		{				
			switch (key_scan())
			{
				case K1: break;
				case K2: break;
				case K3: break;
				case K4: stop[a]=0;delay_ms(100);
						 if(alarm[a][3]==0)
							repeat[a][b]=0;
						 break;
			}
		}
		/*********闹钟响显示时间*********/		
		DS1302_ReadTime();
		LCD1602_DisplayData();
		if(AM_PM==0&&hour12_24==1)
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData('A');
		}
		if(AM_PM==1&&hour12_24==1)
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData('P');
		}
		if(hour12_24==0)
		{
			LCD1602_WriteCom(0x80+13);
			LCD1602_WriteData(' ');
		}
		LCD1602_WriteCom(0xc0+15);
		if(aflag)
			LCD1602_WriteData('N');
		else 
			LCD1602_WriteData('F');
		/********判断响一分钟的时间********/
		if((alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))
			nflag=1;
		else
		{
			nflag=0;
		    stop[a]=1;
			if(alarm[a][3]==0)
				repeat[a][b]=0;
			
		}
		enable=1;
		mflag+=1;		
	}	 
	beep=1;enable=0;TR0=0;
	if(!(alarm[a][0]==TIME[1]&&alarm[a][1]==TIME[2]))
		stop[a]=1;
 }
void InterruptTmr0() interrupt 1 
{  
	TH0=Temp_TH0;
	TL0=Temp_TL0;
	tmrFlg = 1;
	if (enable)
    beep=!beep;
	else
	beep=1;
	
}
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
#define uchar unsigned char
#define uint unsigned int 
void delay_ms(uint i);
void delay_us(uchar x);
#endif
delay.c
#include "delay.h"
void delay_ms(uint i)
{
	uchar n;
 	while(i--)
	for(n=0;n<80;n++)
	;
}
void delay_us(uchar x)	//x*10 us
{
    uchar a,b;
    for(b=x;b>0;b--)
        for(a=1;a>0;a--);
}
Ds18b20.h
#ifndef __TEMP_H_
#define __TEMP_H_
#include "reg51.h"
#include "delay.h"
#include"intrins.h"
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif



sbit WDIO=P3^7;
uchar DS18B20_Init();
void DS18B20_WriteByte(uchar dat);
uchar DS18B20_ReadByte();
void DS18B20_ChangeTemp();
void DS18B20_ReadTempCom();
int DS18B20_ReadTemp();
void LCD1602_DisplayTemp(int temp);
#endif
Ds18b20.c
#include "temp.h"
#include "lcd1602.h"
uchar DS18B20_Init()
{
	uint i=0;
	WDIO=0;		   //总线拉低
//	i=70;	
//	while(i--);//延时642us
	delay_us(32);  //延时720us
	WDIO=1;		   //总线拉高
	i=0;
	while(WDIO)	   //等待是否拉低,
	{
		i++;
		if(i>5000)
			return 0;
	}
	return 1;
}
void DS18B20_WriteByte(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
		WDIO=0;
		_nop_();
//		j++;
		 
		WDIO=dat&0x01;
//		j=6;
//		while(j--); 
		delay_us(4);
		WDIO=1;
		dat>>=1;
	}
}
uchar DS18B20_ReadByte()
{
	 uchar byte,b;
	 uchar i;
	 for(i=0;i<8;i++)
	 {
	 	WDIO=0;
//		j++;
		_nop_();
		WDIO=1;
//		j++;
//		j++;
		delay_us(1);
		b=WDIO;
		byte=(byte>>1)|(b<<7);
//		j=4;
//		while(j--);
		delay_us(5);
	 }
	 return byte;
}
void DS18B20_ChangeTemp()
{
	DS18B20_Init();
	delay_ms(1);
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0x44);
	delay_ms(100);
}
void DS18B20_ReadTempCom()
{
	DS18B20_Init();
	delay_ms(1);
	DS18B20_WriteByte(0xcc);
	DS18B20_WriteByte(0xbe);
}
int DS18B20_ReadTemp()
{
	int temp;
	uchar tmh,tml;
	DS18B20_ChangeTemp();
	DS18B20_ReadTempCom();
	tml=DS18B20_ReadByte();
    tmh=DS18B20_ReadByte();
	temp=tmh;
	temp<<=8;
	temp|=tml;
	return temp;
}
void LCD1602_DisplayTemp(int temp)
{
	float tp;
		uchar i;
		uchar Temp_datas[]={0,0,0,0,0};
	if(temp<0)
	{
		LCD1602_WriteCom(0xc0+10);
		LCD1602_WriteData('-');
		temp=temp-1;
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5;
	}
	else
	{
		LCD1602_WriteCom(0xc0+10);
		LCD1602_WriteData(' ');
		temp=temp-1;
		tp=temp;
		temp=tp*0.0625*100+0.5;
	}
	Temp_datas[0]=temp%10000/1000;
	Temp_datas[1]=temp%1000/100;

	Temp_datas[3]=temp%100/10;
	Temp_datas[4]=temp%10;
	for(i=0;i<2;i++)
	{
		LCD1602_WriteData('0'+Temp_datas[i]);	
	}
	LCD1602_WriteData('C');
}

lcd1602.h
#ifndef __LCD1602_H
#define __LCD1602_H
#define LCD1602_4PINS
#include "delay.h"
#define LCD1602_DATAPINS P0

sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;


void LCD1602_WriteCom(uchar com);			  //写入命令
void LCD1602_WriteData(uchar dat);			 //写入数据
void LCD1602_Init();						     //LCD初始化子程序
void LCD1602_Cursor(uchar addr,uchar Data);
#endif
lcd1602.c
#include "lcd1602.h"
//#ifndef 	LCD1602_4PINS	 //当没有定义这个LCD1602_4PINS时
void LCD1602_WriteCom(uchar com)	  //写入命令
{
	LCD1602_E=0;
	LCD1602_RS=0;
	LCD1602_RW=0;
	LCD1602_DATAPINS=com;
	delay_ms(1);
	LCD1602_E=1;
	delay_ms(1);
	LCD1602_E=0;
}
//#else 
//void LCD1602_WriteCom(uchar com)	  //写入命令
//{
//	LCD1602_E=0;
//	LCD1602_RS=0;
//	LCD1602_RW=0;
//	LCD1602_DATAPINS=com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
//	delay_ms(1);
//	LCD1602_E=1;
//	delay_ms(1);
//	LCD1602_E=0;
//	delay_ms(1);
//	LCD1602_DATAPINS=com<<4;
//	delay_ms(1);
//	LCD1602_E=1;
//	delay_ms(1);
//	LCD1602_E=0;
//}
//#endif
//#ifndef 	LCD1602_4PINS
void LCD1602_WriteData(uchar dat)			//写入数据
{
	LCD1602_E=0;
	LCD1602_RS=1;
	LCD1602_RW=0;
	LCD1602_DATAPINS=dat;
	delay_ms(1);
	LCD1602_E=1;
	delay_ms(1);
	LCD1602_E=0;
}
//#else
//void LCD1602_WriteData(uchar dat)			//写入数据
//{
//	LCD1602_E=0;
//	LCD1602_RS=1;
//	LCD1602_RW=0;
//	LCD1602_DATAPINS=dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
//	delay_ms(1);
//	LCD1602_E=1;
//	delay_ms(1);
//	LCD1602_E=0;
//	LCD1602_DATAPINS=dat<<4;
//	delay_ms(1);
//	LCD1602_E=1;
//	delay_ms(1);
//	LCD1602_E=0;
//}
//#endif
//#ifndef		LCD1602_4PINS
void LCD1602_Init()						     //LCD初始化子程序
{
 	LCD1602_WriteCom(0x38);  				 //开显示
	LCD1602_WriteCom(0x0c); 				 //开显示不显示光标
	LCD1602_WriteCom(0x06); 				 //写一个指针加1
	LCD1602_WriteCom(0x01); 				 //清屏
	LCD1602_WriteCom(0x80);  				 //设置数据指针起点
}
//#else
//void LCD1602_Init()
//{
//	LCD1602_WriteCom(0x32);  
//    LCD1602_WriteCom(0x28);  				 //开显示
//	LCD1602_WriteCom(0x0c); 				 //开显示不显示光标
//	LCD1602_WriteCom(0x06); 				 //写一个指针加1
//	LCD1602_WriteCom(0x01); 				 //清屏
//	LCD1602_WriteCom(0x80);  				 //设置数据指针起点
//}
//#endif
void LCD1602_Cursor(uchar CF,uchar addr)
{
	 LCD1602_WriteCom(CF);
	 LCD1602_WriteCom(addr);
}
Ds1302.h
#ifndef __DS1302_H_
#define __DS1302_H_

#include "reg51.h"
#include "intrins.h"

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif


sbit DSIO=P3^4;
sbit DSCE=P3^5;
sbit SCLK=P3^6;
 
 void DS1302_lock();	 	// 开启写保护
 void DS1302_unlock(); 		//取消写保护
 void DS1302Write(uchar addr,uchar dat);
 uchar DS1302Read(uchar addr);
 void DS1302_Init();
 void DS1302_ReadTime();
 extern uchar TIME[7];	//加入全局变量
 void LCD1602_DisplayData();
#endif
Ds1302.c
#include "ds1302.h"
#include "lcd1602.h"

//DS1302写入和读取时分秒的地址命令
uchar code READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分时日月周年 最低位读写位};
uchar code WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//DS1302时钟初始化2013年1月1日星期二12点00分00秒。存储顺序是秒分时日月周年,存储格式是用BCD码
uchar TIME[7]={0,0x00,0x20,0x07,0x12,0x05,0x18};
//uchar code T[]={"T "};
//uchar code D[]={"D "};
void DS1302Write(uchar addr,uchar dat)
{
	uchar i;
	DSCE=0;
	_nop_();
	SCLK=0;
	_nop_();
	DSCE=1;
	_nop_();
	for(i=0;i<8;i++)
	{
		DSIO=addr&0x01;
		addr>>=1;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
	}
	for(i=0;i<8;i++)
	{
		DSIO=dat&0x01;
		dat>>=1;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
	}
	DSCE=0;
	_nop_();
}
uchar DS1302Read(uchar addr)
{
	uchar i,dat,dat1;
	DSCE=0;
	_nop_();
	SCLK=0;
	_nop_();
	DSCE=1;
	_nop_();
	for(i=0;i<8;i++)
	{
		DSIO=addr&0x01;
		addr>>=1;
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
	}
	_nop_();
	for(i=0;i<8;i++)
	{
		dat1=DSIO;		
		dat=(dat>>1)|(dat1<<7);
		SCLK=1;
		_nop_();
		SCLK=0;
		_nop_();
	}
//	DSCE=0;
	_nop_();
	SCLK=1;
	DSIO=0;
	_nop_();
	DSIO=1;
	_nop_();
	return dat;
}

 void DS1302_lock()	 	// 开启写保护
 {
	DS1302Write(0x8E,0x80);
 }
 void DS1302_unlock() 		//取消写保护
 {
 	DS1302Write(0x8E,0X00);	
 }
void DS1302_Init()
{
	uchar n;
	DS1302_unlock();		 //禁止写保护,就是关闭写保护功能
	for(n=0;n<7;n++)//写入7个字节的时钟信号:分秒时日月周年
	{
//		DS1302Write(0x84,TIME[2]|0x80);
		DS1302Write(WRITE_RTC_ADDR[n],TIME[n]);	
	}
	DS1302_lock();		 //打开写保护功能
}
void DS1302_ReadTime()
{
	uchar n;
	for(n=0;n<7;n++)//读取7个字节的时钟信号:分秒时日月周年
	{
//		TIME[2]=DS1302Read(0x85);
//		TIME[2]<<=3;
//		TIME[2]>>=3;//前三位置0
		TIME[n]=DS1302Read(READ_RTC_ADDR[n]);
	}
		
}
//void LCD1602_DisplayData()
//{
	uchar i;
//	LCD1602_WriteCom(0x80+0X40);
	for(i=0;i<2;i++)
	LCD1602_WriteData(T[i]);
//	LCD1602_WriteData('T');
//	LCD1602_WriteData(' ');
//	if(hour12_24==0)
//	{
//	LCD1602_WriteData('0'+TIME[2]/16);				//时
//	LCD1602_WriteData('0'+(TIME[2]&0x0f));			
//	}	 
//	LCD1602_WriteData(':');
//	LCD1602_WriteData('0'+TIME[1]/16);				//分
//	LCD1602_WriteData('0'+(TIME[1]&0x0f));	
//	LCD1602_WriteData(':');
//	LCD1602_WriteData('0'+TIME[0]/16);				//秒
//	LCD1602_WriteData('0'+(TIME[0]&0x0f));
//
//	LCD1602_WriteCom(0x80);
	for(i=0;i<2;i++)
	LCD1602_WriteData(D[i]);
//	LCD1602_WriteData('D');
//	LCD1602_WriteData(' ');
//	LCD1602_WriteData('2');
//	LCD1602_WriteData('0');
//	LCD1602_WriteData('0'+TIME[6]/16);			//年
//	LCD1602_WriteData('0'+(TIME[6]&0x0f));
//	LCD1602_WriteData('-');
//	LCD1602_WriteData('0'+TIME[4]/16);			//月
//	LCD1602_WriteData('0'+(TIME[4]&0x0f));
//	LCD1602_WriteData('-');
//	LCD1602_WriteData('0'+TIME[3]/16);			//日
//	LCD1602_WriteData('0'+(TIME[3]&0x0f));
//	LCD1602_WriteCom(0x8f);
//	LCD1602_WriteData('0'+(TIME[5]&0x07));	//星期			
//}
key.h
#ifndef __KEY_H
#define __KEY_H
 
#include "sys.h"
#include "delay.h"
 
 
#define KEYPORT P1  //   四个按键接在了P1口的四个引脚#define NO_KEY   0xf0#define K1    0X01#define K2    0X02#define K3    0X03#define K4   0X04#define KEYSUB    0X02#define KEYADD    0X01#define KEYSET    0X04#define KEYNEXT   0X03 //K1,2,3,4,和这些是一样的,只是写.c文件时#define LONGCNT  150#define SHORTCNT 12
#define K1 1
#define K2 2
#define K3 3
#define K4 4 
 
 
 uchar key_scan();


#endif
key.c
#include"key.h"
sbit KeyPort0=P1^4;
sbit KeyPort1=P1^5;						
sbit KeyPort2=P1^6;
sbit KeyPort3=P1^7;	
//sbit KeyPort2=P1^2;
//sbit KeyPort0=P1^0;						
//sbit KeyPort1=P1^1;
//sbit KeyPort3=P1^3;
 
/************************************************************************
函数名称:key_scan()
函数功能:4个独立按键检测
输入参数:无
返回值:KeyV		通过返回值的不同来确定哪个按键被按下
*************************************************************************/ 
uchar key_scan()
{
	uchar KeyV;
	KEYPORT=0xff;		//从51IO口读数据,一般要先给锁存器写1,
						//具体请参考51IO口内部结构						
	if(KeyPort0==0||KeyPort1==0||KeyPort2==0||KeyPort3==0)		//判断是否有按键按下
	//这里改成if((P3&0xf0)!=0xf0)总是错,原因可能是P3读数据不是从引脚读的
	//而是从锁存器读的,一直是0xff
	{
		delay_ms(10);		//防止抖动(拿板子实验时,发现这里延不延时并无影响)
		 if(KeyPort0==0)		//判断哪个按键被按下//
		{	
			KeyV=K1;
		}
		else if(KeyPort1==0)
		{
			KeyV= K2;
		}
		else if(KeyPort2==0)
		{	
			KeyV=K3;
		}
		else if(KeyPort3==0)
		{
			KeyV=K4;
		}
		}
		else 
		{
			KeyV= 0;
		}		  			//判断哪个按键被按下//
		
//		if(KeyV != 0)		//有按键按下时,进行松手检测
 //             while(KeyPort0==0||KeyPort1==0||KeyPort2==0||KeyPort3==0);
		//delay_ms(10);		//延时消抖
   
 
    return KeyV;			//返回KeyV来标识哪一个按键被按下
}
keyProcess.h
#ifndef __KEYPROCESS_H
#define __KEYPROCESS_H
 
#include "sys.h"
#include "stdio.h"
#include "delay.h"
#include "key.h"
#include "ds1302.h"
#include "lcd1602.h"
 

extern uchar alarm[5][5];
extern uchar repeat[5][7];
extern int Clock;
#define MODE0 		0
#define MODE1		1
#define MODE2 		2
#define MODE3		3
#define TIMESET		MODE0	
#define DATESET		MODE1
#define ALARMSET	MODE2
#define SECCON		MODE3
 
void key_process(uchar mode);
 
#endif
keyProcess.c
#include"keyProcess.h"
#include "lcd1602.h"
#include "temp.h"
#include "ds1302.h"
#include "otherProcess.h"
 

/****************************************************************************************************
函数名称:key_process(uchar mode)
函数功能:按键处理函数(调节日期,时间,闹钟)
输入参数:mode		用来选择模式,是修改日期,时间还是闹钟
返回值:无
****************************************************************************************************/



uchar alarm[5][5]={0}; //0-4个闹钟//alarm[0][0] 分钟设置,alarm[0][1] 小时设置,alarm[0][2] 重复/不重复,alarm[0][3] 选择音乐
uchar repeat[5][7]={0};			//重复
int Clock;					//闹钟个数
uchar code timeSet[]={"1:timeSet"};
uchar code alarmSet[]={"2:alarmSet"};
void key_process(uchar mode)
{
	bit flag=0;	   //退出标志位
	int Wch=0;   //时间设置标志
	uchar AlarmWch=0; 	//闹钟设置标志
	uchar n;
	uchar t;
	bit year=1;		   //闰年判断
	int function=0;    //功能选择
	int ClockWch=0;	   //位置选择
	int ClockNum=0;	   //闹钟x
	switch(mode)
	{
		case MODE0:		 	//打开菜单
			LCD1602_WriteCom(0x01);
			LCD1602_WriteCom(0x80);
			for(t=0;t<9;t++)
				LCD1602_WriteData(timeSet[t]);
			LCD1602_WriteCom(0xC0);
			for(t=0;t<10;t++)
				LCD1602_WriteData(alarmSet[t]);		
			LCD1602_Cursor(0x0F,0x80);
			while(1)
			 {
			 	 delay_ms(500);
				 if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
				 {
					
				 	switch(key_scan())
					{
				 	case K1:
					/****************设置时间***************/         
							if(function==0)   	    
							{
							/***********时间显示***********/
								DS1302_ReadTime();
								LCD1602_DisplayData();
								if(AM_PM==0&&hour12_24==1)
								{
									LCD1602_WriteCom(0x80+13);
									LCD1602_WriteData('A');
									LCD1602_WriteCom(0xC0+13);
									LCD1602_WriteData('1');
									LCD1602_WriteData('2');
								}
								if(AM_PM==1&&hour12_24==1)
								{
									LCD1602_WriteCom(0x80+13);
									LCD1602_WriteData('P');
									LCD1602_WriteCom(0xC0+13);
									LCD1602_WriteData('1');
									LCD1602_WriteData('2');
								}
								if(hour12_24==0)
								{
									LCD1602_WriteCom(0xC0+13);
									LCD1602_WriteData('2');
									LCD1602_WriteData('4');
								}
								LCD1602_Cursor(0x0F,0xC0+9);
					/**********按键处理修改时间**********/
								while(1)
								{
								     delay_ms(500);
									 if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
									 {
									 	 switch(key_scan())
										 {
										 	case K1:	Wch++;if(Wch>7) Wch=0; 						  //选择时间的哪一位被更改
												/***********光标显示哪个被选中*********/
														if(Wch<3)
														LCD1602_Cursor(0x0F,0xC0+9-3*Wch);
														if(Wch==3)
														LCD1602_Cursor(0x0F,0x80+11);
														if(Wch==4)
														LCD1602_Cursor(0x0F,0x80+8);
														if(Wch==5)
														LCD1602_Cursor(0x0F,0x80+15);
														if(Wch==6)
														LCD1602_Cursor(0x0F,0x80+5);
														if(Wch==7)
														LCD1602_Cursor(0x0F,0xC0+14);
														break;			  
											case K2:				   								//K2按下,数字加一
														TIME[Wch]++;
												/********时间修改上限*********/			
														if((TIME[Wch]&0x0f)>9)					 //换成BCD码。
														{
															TIME[Wch]=TIME[Wch]+6;
														}
														if((TIME[Wch]>=0x60)&&(Wch<2))		//分秒只能到59
														{
															TIME[Wch]=0;
														}
														if((TIME[Wch]>=0x24)&&(Wch==2))		//小时只能到23
														{
															TIME[Wch]=0;
														}														
														if((TIME[Wch]>=0x32)&&(TIME[4]==1||TIME[4]==3||TIME[4]==5||TIME[4]==7||TIME[4]==8||TIME[4]==0x10||TIME[4]==0x12)&&(Wch==3))		//日只能到31
														{
															TIME[Wch]=1;	
														}
														if((TIME[Wch]>=0x31)&&(TIME[4]==4||TIME[4]==6||TIME[4]==9||TIME[4]==0x11)&&(Wch==3))		//日只能到30
														{
															TIME[Wch]=1;	
														}
														if(TIME[4]==2&&(((uint)(TIME[6]+2000)%4==0&&(uint)(TIME[6]+2000)%100!=0)||((uint)(TIME[6]+2000)%400==0)))	 //润年判断
															year=1;					 //1为闰年
														else
															year=0;					 //0不是闰年
														if((TIME[Wch]>=0x30)&&(TIME[4]==2)&&(Wch==3)&&year==1)		//日只能到29
														{
															TIME[Wch]=1;	
														}
														if((TIME[Wch]>=0x29)&&(TIME[4]==2)&&(Wch==3)&&year==0)		//日只能到28
														{
															TIME[Wch]=1;	
														}
														if((TIME[Wch]>=0x13)&&(Wch==4))		//月只能到12
														{
															TIME[Wch]=1;
														}	
														if((TIME[Wch]>0x7)&&(Wch==5))		//周只能到7
														{
															TIME[Wch]=1;
														}
														if(Wch==7)							//改变时间制
														{
															hour12_24=!hour12_24;
														}
														if(hour12_24==0)					//0为24小时制
														{
															 LCD1602_WriteCom(0x80+13);
															 LCD1602_WriteData(' ');
														}
														LCD1602_DisplayData();				//显示修改时间
														if(AM_PM==0&&hour12_24==1)			//判断12小时制上午
														{
															LCD1602_WriteCom(0x80+13);
															LCD1602_WriteData('A');
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('1');
															LCD1602_WriteData('2');
														}
														if(AM_PM==1&&hour12_24==1)			//判断12小时制下午
														{
															LCD1602_WriteCom(0x80+13);
															LCD1602_WriteData('P');
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('1');
															LCD1602_WriteData('2');
														}
														if(hour12_24==0)					  //显示24小时制
														{
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('2');
															LCD1602_WriteData('4');
														}
														/**********开光标显示修改位置*********/
														if(Wch<3)
														LCD1602_Cursor(0x0F,0xC0+9-3*Wch);
														if(Wch==3)
														LCD1602_Cursor(0x0F,0x80+11);
														if(Wch==4)
														LCD1602_Cursor(0x0F,0x80+8);
														if(Wch==5)
														LCD1602_Cursor(0x0F,0x80+15);
														if(Wch==6)
														LCD1602_Cursor(0x0F,0x80+5);
														if(Wch==7)
														LCD1602_Cursor(0x0F,0xC0+14);
														DS1302_Init();
														break;
														break;		
											case K3:		TIME[Wch]--;					 //K3按下,数字减一	//有毒,待改
														if((TIME[Wch]==0x00-1)&&(Wch<2))		//分秒只能到59
														{
															TIME[Wch]=0x59;
														}
														if((TIME[Wch]==0x00-1)&&(Wch==2))		//小时只能到23
														{
															TIME[Wch]=0x23;
														}
//														if((TIME[Wch]==0x00-1)&&(Wch==2)&&hour12_24==1)		//小时只能到12		  待改
//														{
//															TIME[Wch]=0x12;
//														}
														if((TIME[Wch]==0x00)&&(TIME[4]==1||TIME[4]==3||TIME[4]==5||TIME[4]==7||TIME[4]==8||TIME[4]==0x10||TIME[4]==0x12)&&(Wch==3))		//日只能到31
														{
															TIME[Wch]=0x31;	
														}
														if((TIME[Wch]==0x00)&&(TIME[4]==4||TIME[4]==6||TIME[4]==9||TIME[4]==0x11)&&(Wch==3))		//日只能到30
														{
															TIME[Wch]=0x30;	
														}
														if(TIME[4]==2&&((((TIME[6]/16*10+TIME[6]&0x0f)+2000)%4==0&&((TIME[6]/16*10+TIME[6]&0x0f)+2000)%100!=0)))
														{
															year=1;
														}
														else if(TIME[4]==2&&(((TIME[6]/16*10+TIME[6]&0x0f)+2000)%400==0))
														{
															year=1;
														}
														else
															year=0;
														
														if((TIME[Wch]==0x00)&&(TIME[4]==2)&&(Wch==3)&&year==1)		//日只能到29
														{
															TIME[Wch]=0x29;	
														}
														if((TIME[Wch]==0x00)&&(TIME[4]==2)&&(Wch==3)&&year==0)		//日只能到28
														{
															TIME[Wch]=0x28;	
														}
														if((TIME[Wch]==0x00)&&(Wch==4))		//月只能到12
														{
															TIME[Wch]=0x12;
														}	
														if((TIME[Wch]==0x00)&&(Wch==5))		//周只能到7
														{
															TIME[Wch]=0x07;
														} 
														if((TIME[Wch]&0x0f)>9)					 //换成BCD码。
														{
															TIME[Wch]=TIME[Wch]-6;
														}
													//	DS1302_ReadTime();
														if(Wch==7)
														{
															hour12_24=!hour12_24;
														}
														if(hour12_24==0)
														{
															 LCD1602_WriteCom(0x80+13);
															 LCD1602_WriteData(' ');
														}
														LCD1602_DisplayData();
														if(AM_PM==0&&hour12_24==1)
														{
															LCD1602_WriteCom(0x80+13);
															LCD1602_WriteData('A');
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('1');
															LCD1602_WriteData('2');
														}
														if(AM_PM==1&&hour12_24==1)
														{
															LCD1602_WriteCom(0x80+13);
															LCD1602_WriteData('P');
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('1');
															LCD1602_WriteData('2');
														}
														if(hour12_24==0)
														{
															LCD1602_WriteCom(0xC0+13);
															LCD1602_WriteData('2');
															LCD1602_WriteData('4');
														}
														if(Wch<3)
														LCD1602_Cursor(0x0F,0xC0+9-3*Wch);
														if(Wch==3)
														LCD1602_Cursor(0x0F,0x80+11);
														if(Wch==4)
														LCD1602_Cursor(0x0F,0x80+8);
														if(Wch==5)
														LCD1602_Cursor(0x0F,0x80+15);
														if(Wch==6)
														LCD1602_Cursor(0x0F,0x80+5);
														if(Wch==7)
														LCD1602_Cursor(0x0F,0xC0+14);
														DS1302_Init();
														break;			  
											case K4:	flag=1;break;			   //保存退出
										 }
									 }
									 /********退出后显示**********/	
									 if(flag==1)
									 {
//									 		DS1302_Init();
//									 	  	LCD1602_DisplayTemp(DS18B20_ReadTemp());
//											DS1302_ReadTime();
//											LCD1602_DisplayData();
											//	delay_ms(1000);
											LCD1602_WriteCom(0x01);
											LCD1602_WriteCom(0x80);
											for(t=0;t<9;t++)
												LCD1602_WriteData(timeSet[t]);
											LCD1602_WriteCom(0xC0);
											for(t=0;t<10;t++)
												LCD1602_WriteData(alarmSet[t]);											
											if(function==0)
												LCD1602_Cursor(0x0F,0x80);
											if(function==1)
												LCD1602_Cursor(0x0F,0xC0);
											flag=0;
											Wch=0;
											break;
									 }
								}
												 
							}
							/********************************闹钟设置*********************************/
							if(function==1)								 
							{
								LCD1602_WriteCom(0x01);
								LCD1602_WriteCom(0x80);
								for(n=0;n<=Clock;n++)
								{	
									if(n>4)
										break;
									LCD1602_WriteData('1'+n);
									LCD1602_WriteData(':');
									if(alarm[n][2]==0)
										LCD1602_WriteData('F');
									else
										LCD1602_WriteData('N');
									LCD1602_WriteData(' ');
									if(n==2)
										LCD1602_WriteCom(0xC0);
									
								}
								LCD1602_WriteCom(0xC0+13);
								LCD1602_WriteData('+');
								LCD1602_WriteCom(0xC0+14);
								LCD1602_WriteData('-');
								if(ClockWch==2)
									LCD1602_Cursor(0x0F,0x80);
								if(ClockWch==3)
									LCD1602_Cursor(0x0F,0x80+4);
								if(ClockWch==4)
									LCD1602_Cursor(0x0F,0x80+8);
								if(ClockWch==5)
									LCD1602_Cursor(0x0F,0xC0);
								if(ClockWch==6)
									LCD1602_Cursor(0x0F,0xC0+4);	
								if(ClockWch==0)
									LCD1602_Cursor(0x0F,0xC0+13);
								if(ClockWch==1)
									LCD1602_Cursor(0x0F,0xC0+14);				   //开显示光标
								while(1)
								{
									delay_ms(500);
							   		if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
				           			{
										switch(key_scan())
										{
											case K1: 							  //确定选择
														if(ClockWch==0)
														{
															Clock++;
															LCD1602_WriteCom(0x01);
															if(Clock>4)
															{
																Clock=4;
															}
														}
														if(ClockWch==1)
														{
															Clock--;
															LCD1602_WriteCom(0x01);
															if(Clock<0)
															{
																Clock=0;
															}
														}		
														if(ClockWch>1)
														{
															ClockNum=ClockWch-2;
															while(1)
															{
																delay_ms(500);
							   									if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
																{
																	switch(key_scan())
																	{
																			case K1:					 //进入闹钟x设置
																					LCD1602_WriteCom(0x01);
																					LCD1602_alarm(0x80,alarm[ClockNum][1],alarm[ClockNum][0]);	//显示闹钟时分
																					LCD1602_Data(0x80+7,'S');					   //开关说明
																					LCD1602_Data(0x80+8,'W');
																					LCD1602_Data(0x80+9,':');
																					if(alarm[ClockNum][2]==0)								//开关闹钟
																						LCD1602_Data(0x80+10,'F');
																					else
																						LCD1602_Data(0x80+10,'N');
																					LCD1602_Data(0x80+12,'R');					   //重复说明
																					LCD1602_Data(0x80+13,'P');
																					LCD1602_Data(0x80+14,':');
																					if(alarm[ClockNum][3]==0)						//显示重复/不重复闹钟
																						LCD1602_Data(0x80+15,'0');				//0不重复
																					else
																						LCD1602_Data(0x80+15,'1');				//1重复
																					LCD1602_Data(0xC0+0,'M');					   //音乐说明
																					LCD1602_Data(0xC0+1,'U');
																					LCD1602_Data(0xC0+2,'S');
																					LCD1602_Data(0xC0+3,'I');
																					LCD1602_Data(0xC0+4,'C');
																					LCD1602_Data(0xC0+5,':');
																					for(n=0;n<5;n++)								   //显示音乐
																					{
																						LCD1602_Data(0xC0+n*2+6,'0'+n);
																					}
																					LCD1602_Cursor(0x0F,0x80+4);					   //开显示光标
																					while(1)
																					{
																						delay_ms(500);
							   															if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
																						{
																							switch(key_scan())
																							{
																								case K1: AlarmWch++;					  // 选择设置 重复/不重复,时间,选择音乐
																										 if(AlarmWch>4)
																										 AlarmWch=0;
																										 if(AlarmWch==3)
																											LCD1602_Cursor(0x0F,0x80+13);
																									 	 break;	
																								case K2: alarm[ClockNum][AlarmWch]++;					  		// 闹钟时间加1
																										 if((alarm[ClockNum][AlarmWch]&0x0f)>9&&AlarmWch<2)		//换成BCD码。
																										 {
																											alarm[ClockNum][AlarmWch]=alarm[Clock][AlarmWch]+6;
																										   	 }	
																									     if((alarm[ClockNum][AlarmWch]>=0x60)&&AlarmWch==0)		//分秒只能到59
																										 {
																											alarm[ClockNum][AlarmWch]=0;
																										 }
																										 if((alarm[ClockNum][AlarmWch]>=0x24)&&(AlarmWch==1))	//小时只能到23
																										 {
																											alarm[ClockNum][AlarmWch]=0;
																										 } 
																										 if(AlarmWch==2&&alarm[ClockNum][AlarmWch]>1)				//开关闹钟
																										 	alarm[ClockNum][AlarmWch]=0;
																										 if(AlarmWch==3&&alarm[ClockNum][AlarmWch]>1)				//重复/不重复
																										 	alarm[ClockNum][AlarmWch]=1;
																										 if(AlarmWch==4&&alarm[ClockNum][AlarmWch]>4)				//选择音乐
																										 	alarm[ClockNum][AlarmWch]=0;
																										 if(AlarmWch==3)						   //选择重复
																										 {	
																											 	LCD1602_WriteCom(0x01);
																												LCD1602_WriteCom(0x80);
																												for(n=0;n<7;n++)
																												{
																													LCD1602_WriteData('n');
																													LCD1602_WriteData(':');
																													LCD1602_WriteData('0'+repeat[Clock][n]);
																													LCD1602_WriteData(' ');
																													if(n==3)
																														LCD1602_WriteCom(0xC0);
																												}
																												LCD1602_Data(0xC0+12,'n');
																												LCD1602_Data(0xC0+13,'=');
																												LCD1602_Data(0xC0+14,'1');
																												LCD1602_Cursor(0x0F,0x80);
																												while(1)
																												{
																				
																													delay_ms(500);
							   																						if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
																													{
																														switch(key_scan())
																														{
																															case K1:   Wch++;if(Wch>6) Wch=0;break;
																															case K2:   repeat[ClockNum][Wch]=1;break;
																															case K3:   repeat[ClockNum][Wch]=0;break;
																															case K4:   flag=1;Wch=0;break;
																														}
																														LCD1602_WriteCom(0x80);
																														for(n=0;n<7;n++)
																														{
																															LCD1602_WriteData('n');
																															LCD1602_WriteData(':');
																															LCD1602_WriteData('0'+repeat[ClockNum][n]);
																															LCD1602_WriteData(' ');
																															if(n==3)
																															LCD1602_WriteCom(0xC0);
																														}
																														LCD1602_Data(0xC0+12,'n');
																														LCD1602_Data(0xC0+13,'=');
																														LCD1602_Data(0xC0+14,'0'+Wch+1);
																														if(Wch==0)
																															LCD1602_Cursor(0x0F,0x80);
																														if(Wch==1)
																															LCD1602_Cursor(0x0F,0x80+4);
																														if(Wch==2)
																															LCD1602_Cursor(0x0F,0x80+8);
																														if(Wch==3)
																															LCD1602_Cursor(0x0F,0x80+12);
																														if(Wch==4)
																															LCD1602_Cursor(0x0F,0xC0);
																														if(Wch==5)
																															LCD1602_Cursor(0x0F,0xC0+4);
																														if(Wch==6)
																															LCD1602_Cursor(0x0F,0xC0+8);
																													}
																													if(flag==1)
																													{
																														flag=0;
																														LCD1602_WriteCom(0x01);
																														LCD1602_alarm(0x80,alarm[Clock][1],alarm[Clock][0]);			   //显示闹钟界面
																														//显示光标
																														LCD1602_Data(0x80+7,'S');					   //开关说明
																														LCD1602_Data(0x80+8,'W');
																														LCD1602_Data(0x80+9,':');
																														if(alarm[ClockNum][2]==0)	 					 //显示开关闹钟
																															LCD1602_Data(0x80+10,'F');				 //0关
																														else
																															LCD1602_Data(0x80+10,'N');				 //1开
																														LCD1602_Data(0x80+12,'R');					   //重复说明
																														LCD1602_Data(0x80+13,'P');
																														LCD1602_Data(0x80+14,':');
																														if(alarm[ClockNum][3]==0)						//显示重复/不重复闹钟
																															LCD1602_Data(0x80+15,'0');				//0不重复
																														else
																															LCD1602_Data(0x80+15,'1');				//1重复
																														LCD1602_Data(0xC0+0,'M');					   //音乐说明
																														LCD1602_Data(0xC0+1,'U');
																														LCD1602_Data(0xC0+2,'S');
																														LCD1602_Data(0xC0+3,'I');
																														LCD1602_Data(0xC0+4,'C');
																														LCD1602_Data(0xC0+5,':');
																														for(n=0;n<5;n++)
																														{
																															 LCD1602_Data(0xC0+n*2+6,'0'+n);
																														}
																														if(AlarmWch==0)								//开显示光标
																															LCD1602_Cursor(0x0F,0x80+4);
																														if(AlarmWch==1)
																															LCD1602_Cursor(0x0F,0x80+1);
																														if(AlarmWch==2)
																															LCD1602_Cursor(0x0F,0x80+10);
																														if(AlarmWch==3)
																															LCD1602_Cursor(0x0F,0x80+14);
																														if(AlarmWch==4)
																														{
																															LCD1602_Cursor(0x0F,0xC0+alarm[ClockNum][4]*2+6);
																														}
																														break;
																													}
																												}						
																											 }
																										 break;
																								case K3: alarm[ClockNum][AlarmWch]--;					 		 // 闹钟时间减1
																										if((alarm[ClockNum][AlarmWch]==0x00-1)&&(AlarmWch==0))	 //分秒只能到59
																										{
																											alarm[ClockNum][AlarmWch]=0x59;
																										}
																										if((alarm[ClockNum][AlarmWch]==0x00-1)&&(AlarmWch==1))		//小时只能到23
																										{
																											alarm[ClockNum][AlarmWch]=0x23;
																										}
																										if((alarm[ClockNum][AlarmWch]&0x0f)>9&&AlarmWch<2)		//换成BCD码。
																										{
																											alarm[ClockNum][AlarmWch]=alarm[ClockNum][AlarmWch]-6;
																										}
																										if(AlarmWch==2&&alarm[ClockNum][AlarmWch]<0)			//开关闹钟
																										 	alarm[ClockNum][AlarmWch]=1;
																										if(AlarmWch==3)									//重复/不重复
																										 	alarm[ClockNum][AlarmWch]=0;
																								    	if(AlarmWch==4&&alarm[ClockNum][AlarmWch]<0)				//选择音乐
																										 	alarm[ClockNum][AlarmWch]=4;

																										if(AlarmWch==3)						   //选择重复
																										 {	
																											 	LCD1602_WriteCom(0x01);
																												LCD1602_WriteCom(0x80);
																												for(n=0;n<7;n++)
																												{
																													LCD1602_WriteData('n');
																													LCD1602_WriteData(':');
																													LCD1602_WriteData('0'+repeat[Clock][n]);
																													LCD1602_WriteData(' ');
																													if(n==3)
																														LCD1602_WriteCom(0xC0);
																												}
																													LCD1602_Data(0xC0+12,'n');
																													LCD1602_Data(0xC0+13,'=');
																													LCD1602_Data(0xC0+14,'1');
																												LCD1602_Cursor(0x0F,0x80);
																												while(1)
																												{
																				
																													delay_ms(500);
							   																						if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//检测有没有按键按下,有按键按下才执行操作
																													{
																														switch(key_scan())
																														{
																															case K1:   Wch++;if(Wch>6) Wch=0;break;
																															case K2:   repeat[ClockNum][Wch]=1;break;
																															case K3:   repeat[ClockNum][Wch]=0;break;
																															case K4:   flag=1;Wch=0;break;
																														}
																														LCD1602_WriteCom(0x80);
																														for(n=0;n<7;n++)
																														{
																															LCD1602_WriteData('n');
																															LCD1602_WriteData(':');
																															LCD1602_WriteData('0'+repeat[ClockNum][n]);
																															LCD1602_WriteData(' ');
																															if(n==3)
																															LCD1602_WriteCom(0xC0);
																														}
																														LCD1602_Data(0xC0+12,'n');
																														LCD1602_Data(0xC0+13,'=');
																														LCD1602_Data(0xC0+14,'0'+Wch+1);
																														if(Wch==0)
																															LCD1602_Cursor(0x0F,0x80);
																														if(Wch==1)
																															LCD1602_Cursor(0x0F,0x80+4);
																														if(Wch==2)
																															LCD1602_Cursor(0x0F,0x80+8);
																														if(Wch==3)
																															LCD1602_Cursor(0x0F,0x80+12);
																														if(Wch==4)
																															LCD1602_Cursor(0x0F,0xC0);
																														if(Wch==5)
																															LCD1602_Cursor(0x0F,0xC0+4);
																														if(Wch==6)
																															LCD1602_Cursor(0x0F,0xC0+8);
																													}
																													if(flag==1)
																													{
																														flag=0;
																														LCD1602_WriteCom(0x01);
																														LCD1602_alarm(0x80,alarm[Clock][1],alarm[Clock][0]);			   //显示闹钟界面
																														//显示光标
																														LCD1602_Data(0x80+7,'S');					   //开关说明
																														LCD1602_Data(0x80+8,'W');
																														LCD1602_Data(0x80+9,':');
																														if(alarm[ClockNum][2]==0)	 					 //显示开关闹钟
																															LCD1602_Data(0x80+10,'F');				 //0关
																														else
																															LCD1602_Data(0x80+10,'N');				 //1开
																														LCD1602_Data(0x80+12,'R');					   //重复说明
																														LCD1602_Data(0x80+13,'P');
																														LCD1602_Data(0x80+14,':');
																														if(alarm[ClockNum][3]==0)						//显示重复/不重复闹钟
																															LCD1602_Data(0x80+15,'0');				//0不重复
																														else
																															LCD1602_Data(0x80+15,'1');				//1重复
																														LCD1602_Data(0xC0+0,'M');					   //音乐说明
																														LCD1602_Data(0xC0+1,'U');
																														LCD1602_Data(0xC0+2,'S');
																														LCD1602_Data(0xC0+3,'I');
																														LCD1602_Data(0xC0+4,'C');
																														LCD1602_Data(0xC0+5,':');
																														for(n=0;n<5;n++)
																														{
																															 LCD1602_Data(0xC0+n*2+6,'0'+n);
																														}
																														if(AlarmWch==0)								//开显示光标
																															LCD1602_Cursor(0x0F,0x80+4);
																														if(AlarmWch==1)
																															LCD1602_Cursor(0x0F,0x80+1);
																														if(AlarmWch==2)
																															LCD1602_Cursor(0x0F,0x80+10);
																														if(AlarmWch==3)
																															LCD1602_Cursor(0x0F,0x80+15);
																														if(AlarmWch==4)
																														{
																															LCD1602_Cursor(0x0F,0xC0+alarm[ClockNum][4]*2+6);
																														}
																														break;
																													}
																												}						
																											 }
																										  break;
																								case K4: flag=1;break;					  // 退出设置
																							}
																							LCD1602_alarm(0x80,alarm[ClockNum][1],alarm[ClockNum][0]);			   //显示闹钟界面
																							//显示光标
																							LCD1602_Data(0x80+7,'S');					   //开关说明
																							LCD1602_Data(0x80+8,'W');
																							LCD1602_Data(0x80+9,':');
																							if(alarm[ClockNum][2]==0)	 					 //显示开关闹钟
																								LCD1602_Data(0x80+10,'F');				 //0关
																							else
																								LCD1602_Data(0x80+10,'N');				 //1开
																							LCD1602_Data(0x80+12,'R');					   //重复说明
																							LCD1602_Data(0x80+13,'P');
																							LCD1602_Data(0x80+14,':');
																							if(alarm[ClockNum][3]==0)						//显示重复/不重复闹钟
																								LCD1602_Data(0x80+15,'0');				//0不重复
																							else
																								LCD1602_Data(0x80+15,'1');				//1重复
																							LCD1602_Data(0xC0+0,'M');					   //音乐说明
																							LCD1602_Data(0xC0+1,'U');
																							LCD1602_Data(0xC0+2,'S');
																							LCD1602_Data(0xC0+3,'I');
																							LCD1602_Data(0xC0+4,'C');
																							LCD1602_Data(0xC0+5,':');
																							for(n=0;n<5;n++)
																							{
																								 LCD1602_Data(0xC0+n*2+6,'0'+n);
																							}
																							if(AlarmWch==0)								//开显示光标
																								LCD1602_Cursor(0x0F,0x80+4);
																							if(AlarmWch==1)
																								LCD1602_Cursor(0x0F,0x80+1);
																							if(AlarmWch==2)
																								LCD1602_Cursor(0x0F,0x80+10);
																							if(AlarmWch==3)
																								LCD1602_Cursor(0x0F,0x80+15);
																							if(AlarmWch==4)
																							{
																								LCD1602_Cursor(0x0F,0xC0+alarm[ClockNum][4]*2+6);
																							}
																						}
																						if(flag==1)											  //退出显示闹钟选择界面
																						{
																						
																							AlarmWch=0;
																						
																							LCD1602_WriteCom(0x01);
																							LCD1602_WriteCom(0x80);
													 										for(n=0;n<=Clock;n++)
																							{	
																								if(n>4)
																							 		 break;
																								LCD1602_WriteData('1'+n);
																								LCD1602_WriteData(':');
																								if(alarm[n][2]==0)
																									LCD1602_WriteData('F');
																								else
																									LCD1602_WriteData('N');
																									LCD1602_WriteData(' ');
																								if(n==2)
																									 LCD1602_WriteCom(0xC0);
																
																							}
																							LCD1602_WriteCom(0xC0+13);
																							LCD1602_WriteData('+');
																							LCD1602_WriteCom(0xC0+14);
																							LCD1602_WriteData('-');
																							if(ClockWch==2)
																								LCD1602_Cursor(0x0F,0x80);
																							if(ClockWch==3)
																								LCD1602_Cursor(0x0F,0x80+4);
																							if(ClockWch==4)
																								LCD1602_Cursor(0x0F,0x80+8);
																							if(ClockWch==5)
																								LCD1602_Cursor(0x0F,0xC0);
																							if(ClockWch==6)
																								LCD1602_Cursor(0x0F,0xC0+4);	
																							if(ClockWch==0)
																								LCD1602_Cursor(0x0F,0xC0+13);
																							if(ClockWch==1)
																								LCD1602_Cursor(0x0F,0xC0+14);
																							break;
																						}
																					}
																					break;
																		case K2:  ClockWch++;  break;	 //选择设置位置加1
																		case K3:  ClockWch--;  break;	 //选择设置位置减1
																		case K4:  flag=1;break;
																	}
																}
																if(flag==1||ClockWch!=(ClockNum+2))
																{
																	flag=0;
																	ClockNum=0;
																	LCD1602_WriteCom(0x01);
																	LCD1602_WriteCom(0x80);
													 				for(n=0;n<=Clock;n++)
																	{	
																		if(n>4)
																	 		 break;
																		LCD1602_WriteData('1'+n);
																		LCD1602_WriteData(':');
																		if(alarm[n][2]==0)
																			LCD1602_WriteData('F');
																		else
																			LCD1602_WriteData('N');
																		LCD1602_WriteData(' ');
																		if(n==2)
																			 LCD1602_WriteCom(0xC0);
																
																	}
																	LCD1602_WriteCom(0xC0+13);
																	LCD1602_WriteData('+');
																	LCD1602_WriteCom(0xC0+14);
																	LCD1602_WriteData('-');
																	if(ClockWch==2)
																		LCD1602_Cursor(0x0F,0x80);
																	if(ClockWch==3)
																		LCD1602_Cursor(0x0F,0x80+4);
																	if(ClockWch==4)
																		LCD1602_Cursor(0x0F,0x80+8);
																	if(ClockWch==5)
																		LCD1602_Cursor(0x0F,0xC0);
																	if(ClockWch==6)
																		LCD1602_Cursor(0x0F,0xC0+4);	
																	if(ClockWch==0)
																		LCD1602_Cursor(0x0F,0xC0+13);
																	if(ClockWch==1)
																		LCD1602_Cursor(0x0F,0xC0+14);
																	break;
																}
															}
														}
														LCD1602_WriteCom(0x80);
														for(n=0;n<=Clock;n++)
														{	
															if(n>4)
																break;
															LCD1602_WriteData('1'+n);
															LCD1602_WriteData(':');
															if(alarm[n][2]==0)
																LCD1602_WriteData('F');
															else
																LCD1602_WriteData('N');
															LCD1602_WriteData(' ');
															if(n==2)
																LCD1602_WriteCom(0xC0);
														}
														LCD1602_WriteCom(0xC0+13);
														LCD1602_WriteData('+');
														LCD1602_WriteCom(0xC0+14);
														LCD1602_WriteData('-');

														if(ClockWch==2)		   //显示光标
															LCD1602_Cursor(0x0F,0x80);
														if(ClockWch==3)
															LCD1602_Cursor(0x0F,0x80+4);
														if(ClockWch==4)
															LCD1602_Cursor(0x0F,0x80+8);
														if(ClockWch==5)
															LCD1602_Cursor(0x0F,0xC0);
														if(ClockWch==6)
															LCD1602_Cursor(0x0F,0xC0+4);	
														if(ClockWch==0)
															LCD1602_Cursor(0x0F,0xC0+13);
														if(ClockWch==1)
															LCD1602_Cursor(0x0F,0xC0+14);
														break;
											case K2:	
														ClockWch++;		 //选择设置位置加1
														
														if(ClockWch>Clock+2)
															 ClockWch=0;
														break;
											case K3:	ClockWch--;		 //选择设置位置减1
														if(ClockWch<0)
															 ClockWch=Clock+2;
														break;
											case K4:	flag=1;break;
										}
									}
//									LCD1602_WriteCom(0x01);				  //显示闹钟个数
									LCD1602_WriteCom(0x80);
									for(n=0;n<=Clock;n++)
									{	
										if(n>4)
											break;
										LCD1602_WriteData('1'+n);
										LCD1602_WriteData(':');
										if(alarm[n][2]==0)
											LCD1602_WriteData('F');
										else
											LCD1602_WriteData('N');
											LCD1602_WriteData(' ');
										if(n==2)
											LCD1602_WriteCom(0xC0);
									
									}
									LCD1602_WriteCom(0xC0+13);
									LCD1602_WriteData('+');
									LCD1602_WriteCom(0xC0+14);
									LCD1602_WriteData('-');

									if(ClockWch==2)		   //显示光标
											LCD1602_Cursor(0x0F,0x80);
										if(ClockWch==3)
											LCD1602_Cursor(0x0F,0x80+4);
										if(ClockWch==4)
											LCD1602_Cursor(0x0F,0x80+8);
										if(ClockWch==5)
											LCD1602_Cursor(0x0F,0xC0);
										if(ClockWch==6)
											LCD1602_Cursor(0x0F,0xC0+4);	
										if(ClockWch==0)
											LCD1602_Cursor(0x0F,0xC0+13);
										if(ClockWch==1)
											LCD1602_Cursor(0x0F,0xC0+14);
										if(flag==1)								//退出显示主菜单 
										{
											flag=0;
											ClockWch=0;							//位置选择置0  
											LCD1602_WriteCom(0x01);
											LCD1602_WriteCom(0x80);
											for(t=0;t<9;t++)
												LCD1602_WriteData(timeSet[t]);
											LCD1602_WriteCom(0xC0);
											for(t=0;t<10;t++)
												LCD1602_WriteData(alarmSet[t]);
											if(function==0)
												LCD1602_Cursor(0x0F,0x80);
											if(function==1)
												LCD1602_Cursor(0x0F,0xC0);
											break;
										 } 
									}
								}
								break;	
					case K2:	function++;	 									 //功能选择
								if(function>1)
									function=0;	
								if(function==0)
									LCD1602_Cursor(0x0F,0x80);
								if(function==1)
									LCD1602_Cursor(0x0F,0xC0);							
								break;
					case K3:    function--;	 									 //功能选择
								if(function<0)
									function=1;
								if(function==0)
									LCD1602_Cursor(0x0F,0x80);
								if(function==1)
									LCD1602_Cursor(0x0F,0xC0);
								break;
					case K4:	flag=1;break;	  //退出设置
				
					}
				 }
				 if(flag==1)										  //退出开主显示界面
				 {
				 			LCD1602_DisplayTemp(DS18B20_ReadTemp());
							DS1302_ReadTime();		     	  
							LCD1602_DisplayData();
							if(AM_PM==0&&hour12_24==1)
							{
								LCD1602_WriteCom(0x80+13);
								LCD1602_WriteData('A');
							}
							if(AM_PM==1&&hour12_24==1)
							{
								LCD1602_WriteCom(0x80+13);
								LCD1602_WriteData('P');
							}
						//	delay_ms(1000);
							flag=0;
							break;
				 }
			 }
			 LCD1602_WriteCom(0x0C);				  //取消光标
			 break;
		case MODE1:		hour12_24=!hour12_24;break;	  //更改时制
							
		case MODE2:		if(hour12_24==1)
						{
						AM_PM=!AM_PM;
						if(AM_PM==1)
						{
							if(TIME[2]==0x08)
								TIME[2]=0x20;
							else if(TIME[2]==0x09)
								TIME[2]=0x21;
							else
								TIME[2]+=0x12;
							DS1302_Init();
						}
						
						if(AM_PM==0)
						{
							if(TIME[2]==0x20)
								TIME[2]=0x08;
							else if(TIME[2]==0x21)
								TIME[2]=0x09;
							else
								TIME[2]-=0x12;
							DS1302_Init();
						}
						}
						break;	//无
		case MODE3:		break;	//开关闹钟
	}
}
otherProcess.h
#ifndef __OTHERPROCESS_H
#define __OTHERPROCESS_H
#include "sys.h"
#include "lcd1602.h"
extern bit hour12_24;
extern bit AM_PM;
extern bit alarm_AM_PM;
void LCD1602_alarm(uchar addr,uchar hour,uchar min);
void LCD1602_Data(uchar addr,uchar dat);
void LCD1602_DisplayData();
#endif
otherProcess.c
#include "otherProcess.h"
#include "ds1302.h"
bit hour12_24=0;
bit AM_PM=0;
bit alarm_AM_PM;
void LCD1602_alarm(uchar addr,uchar hour,uchar min)
{
	uchar i;
	if(hour12_24==0)
	{
	LCD1602_WriteCom(addr);
	LCD1602_WriteData('0'+hour/16);				//时
	LCD1602_WriteData('0'+(hour&0x0f));
	}
	if(hour12_24==1)
	{
		if(hour>0x12)
		{
			i=hour-0x12;
				alarm_AM_PM=1;
			if(hour==0x20)
				i=0x08;
			if(hour==0x21)
				i=0x09;
		}
		else											  //早上
		{		
			alarm_AM_PM=0;
			i=hour;
			if(hour==0x12)
				alarm_AM_PM=1;
			if(hour==0x00)
				i=0x12;
		}
		LCD1602_WriteCom(addr);
		LCD1602_WriteData('0'+i/16);				//时
		LCD1602_WriteData('0'+(i&0x0f));
		if(alarm_AM_PM==0)
		{
			LCD1602_WriteCom(addr+5);
			LCD1602_WriteData('A');
		}
		else
		{
			LCD1602_WriteCom(addr+5);
			LCD1602_WriteData('P');
		}
	}	
	LCD1602_WriteCom(addr+2);
	LCD1602_WriteData(':');
	LCD1602_WriteData('0'+min/16);				//分
	LCD1602_WriteData('0'+(min&0x0f));	

}
void LCD1602_Data(uchar addr,uchar dat)		   //写一个地址和数据
{
	LCD1602_WriteCom(addr);
	LCD1602_WriteData(dat);
}
void LCD1602_DisplayData()
{
	uchar i;
	LCD1602_WriteCom(0x80+0X40);
//	for(i=0;i<2;i++)
//	LCD1602_WriteData(T[i]);
	LCD1602_WriteData('T');
	LCD1602_WriteData(' ');
	if(hour12_24==0)
	{
		LCD1602_WriteCom(0x80+0X40+2);
		LCD1602_WriteData('0'+TIME[2]/16);				//时
		LCD1602_WriteData('0'+(TIME[2]&0x0f));			
	}
	if(hour12_24==1)
	{
		if(TIME[2]>0x12)								   //下午
		{	
			i=TIME[2]-0x12;
			AM_PM=1;
			if(TIME[2]==0x20)
				i=0x08;
			if(TIME[2]==0x21)
				i=0x09;
		}
		else											  //早上
		{		
			AM_PM=0;
			i=TIME[2];
			if(TIME[2]==0x12)
				AM_PM=1;
			if(TIME[2]==0x00)
				i=0x12;
		}
			LCD1602_WriteCom(0x80+0X40+2);
			LCD1602_WriteData('0'+i/16);				//时
			LCD1602_WriteData('0'+(i&0x0f));
					
	}
	LCD1602_WriteCom(0x80+0X40+4);	 
	LCD1602_WriteData(':');
	LCD1602_WriteData('0'+TIME[1]/16);				//分
	LCD1602_WriteData('0'+(TIME[1]&0x0f));	
	LCD1602_WriteData(':');
	LCD1602_WriteData('0'+TIME[0]/16);				//秒
	LCD1602_WriteData('0'+(TIME[0]&0x0f));

	LCD1602_WriteCom(0x80);
//	for(i=0;i<2;i++)
//	LCD1602_WriteData(D[i]);
	LCD1602_WriteData('D');
	LCD1602_WriteData(' ');
	LCD1602_WriteData('2');
	LCD1602_WriteData('0');
	LCD1602_WriteData('0'+TIME[6]/16);			//年
	LCD1602_WriteData('0'+(TIME[6]&0x0f));
	LCD1602_WriteData('-');
	LCD1602_WriteData('0'+TIME[4]/16);			//月
	LCD1602_WriteData('0'+(TIME[4]&0x0f));
	LCD1602_WriteData('-');
	LCD1602_WriteData('0'+TIME[3]/16);			//日
	LCD1602_WriteData('0'+(TIME[3]&0x0f));
	LCD1602_WriteCom(0x8f);
	LCD1602_WriteData('0'+(TIME[5]&0x07));	//星期			
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

电子闹钟设计 的相关文章

随机推荐

  • 获取table中的所有行中的td值,包括input值和select值等

    首先获取表对象document getElementById onceFeeTableId 然后通过循环可以获取所有的行 tableObj rows i 如果有需要可在循环里面再加一个循环 用来循环所有的列 HTML table class
  • 【Mysql 存储过程 Or 存储函数 傻傻分不清? 】

    MySQL的存储函数 自定义函数 和存储过程都是用于存储SQL语句的 但是什么时候用什么呢 是不是总是傻傻的分不清 本文来详细的讲一下存储函数 和存储过程 以后再也不会迷糊 存储函数 存储过程 一 异同点 二 存储函数 语法 三 存储过程
  • Ubuntu 20.04上安装和配置MySql5.7

    此博客作为学习笔记使用 仅供用于学习 勿用于任何非法用途 Ubuntu换源 ubuntu 20 04系统自带源直接安装是MySQL 8 0 我要安装MySQL 5 7的版本的所以先进行换源 1 1 备份原来的sorce文件 sudo cp
  • 深度之眼(四)——Python基本数据类型

  • 使用NPM发布uni-app,Vue自定义组件

    使用NPM发布uni app以及vue自定义组件 使用npm install 安装他人发布的组件平时用的比较多 操作也比较简单 最近自己捣鼓了一下 如何发布自己的自定义组件方便自己和他人使用npm install 安装 编写组件 第一步是本
  • 多线程进阶(下)

    目录 一 JUC 二 线程安全的集合类 三 死锁 一 JUC 这里的juc指的是java util concurrent 并发 多线程相关的 一个标准库中的类 下面是JUC里面的常见类 Callable 这是一个interface 也是一种
  • 样本选择模型 & 处理效应模型

    一 样本选择偏差与自选择偏差 样本选择偏差 样本选择偏差的非随机选择机制在于对样本的选择不随机 在样本数据的采集过程中 只对某部分群体进行调查 但这部分群体与其他群体在某些方面的特征差异较大 因此根据这样的样本做回归得到的普适性结论并不可信
  • iOS自定义下拉刷新控件

    自定义下拉刷新控件 概述 用了很多的别人的下拉刷新控件 想写一个玩玩 自定义一个在使用的时候也会比较有意思 使应用更加的灵动一些 毕竟谁不喜欢各种动画恰到好处的应用呢 使用方式如下 tableview refreshControl XRef
  • 运维实践

    欢迎关注 WeiyiGeek 点击 下方卡片 即可关注我哟 设为 星标 每天带你 基础入门 到 全栈实践 再到 放弃学习 涉及 网络安全运维 应用开发 物联网IOT 学习路径 个人感悟 等知识 花开堪折直须折 莫待无花空折枝 作者主页 ht
  • 初级1 题目二 选择排序

    1 选择排序和冒泡排序很类似 不过冒泡排序是两两比较 每次确定一个元素的位置 而选择排序是一个和其他所有未确定的元素进行比较 然后确定位置 include
  • 如何提高影响力?

    一 什么是影响力 1 通俗的讲 影响力就是影响他人的能力 二 为什么需要提高 1 可以让工作更高效 2 可以让生活更惬意 三 提高影响力的切入点 1 乐于助人与虚心求教 1 1 每个人都会遇到困难 在别人遇到困难的时候 帮助其一下 不要担心
  • js 数组根据字段分组

    在平时的开发中 难免会遇到需要对接口获取的数据进行处理 例如以下数据 const arr a 系列1 b 2 c 3 a 系列2 b 2 c 3 a 系列3 b 2 c 3 我们需要对a字段进行分组 将b和c字段单独取出来 那么我们就可以用
  • 微信小程序注册入口和注册流程(完整版图文教程)

    微信小程序注册是免费的 在腾讯云微信公众平台即可注册 无论是个人 企业都可以免费注册微信小程序 先输入邮箱注册激活 然后填写主体类型对应的证件信息 最后管理员身份验证使用维信扫一扫即可 小程序5来详细说下微信小程序注册入口和微信小程序注册流
  • 下载Android特定模块的源代码

    原文地址 http www apkbus com android 18828 1 1 html 开发中要模仿Android系统中某些应用的特性 需查看其源代码 关于Android源码的介绍见 http source android com
  • Go依赖管理及Go module使用

    目录 一 依赖管理 二 为什么需要依赖管理 三 godep 3 1 安装 3 2 基本命令 3 3 使用godep 3 4 vender机制 3 5 godep开发流程 四 go module 4 1 GO111MODULE 4 2 GOP
  • 周杰伦演唱会总是抢不到票?教你用Python做一个自动抢票脚本

    相信想去周董演唱会的大家都用过大麦网抢票吧 可是 抢不到啊 该说不说 我抢到了 那么 今天带大家用Python来制作一个自动抢票的脚本小程序 知识点 面向对象编程 selenium 操作浏览器 pickle 保存和读取Cookie实现免登陆
  • 微信公众号分享功能 errMsg: “config:fail,Error: 系统错误,错误码:63002,invalid signature [20210130 10:16:32][]“

    H5 分享 请求分享页面时 系统错误 errMsg config fail Error 系统错误 错误码 63002 invalid signature 20210130 10 16 32 解决方案 报错信息 签名错误 需要检查自己的签名是
  • 反转数组(两种方法)

    a 第一种方法 创建一个新数组接收并返回 var arr1 1 2 3 var arr2 reverse1 arr1 console log arr2 console log reverse1 arr1 定义一个新数组 把老数组中的元素反向
  • UsbWebserver + MySQL + Apache的和环境配置问题(主要是连不上MySQL的问题)

    问题1 Apche感叹号 是因为软件路径中含有中文 可以把文件转移到没中文的路径下 问题2 mysqli connect Server sent charset 255 unknown to the client php集成环境 usbwe
  • 电子闹钟设计

    摘要 本设计是以89c51单片机作为控制核心的闹铃系统 本文大致可以分三个章节 第一章讲用单片机制作电子闹钟带来的优势 还有电子闹钟在未来的电子产品中的趋势以及本次设计所要实现的课题目标 第二章讲一些设计思路和硬件组成 第三讲程序代码 最后