#include <reg52.h>
#include <intrins.h>
#include "i2c.h"    //包含i2c.h头文件，注意自建的头文件是用双引号
#define uchar unsigned char
#define uint unsigned int
bit ds18b20_flag;   //DS18B20标记位
uchar code table1[]="20  -  -  ";    //液晶一直显示的字符，共10个字符位
uchar code table2[]="  :  :      ";   //共12个字符位
uchar code table3[]="Alarm set:";
uchar miao,fen,shi,nian,yue,ri,week,wendu_shi,wendu_ge,wendu_shu,variate,alarm_shi,
     alarm_fen,alarm_miao;
uchar flag=1,count=0,flag_up=0,flag_down=0,flag_alarm=0,alarm_on,
     alarm_count=0,done=0;  //变量声明并赋初值
uint  temp,wendu;

/***************************** 定义IO ****************************/
sbit ds1302_sclk= P1^7;    //DS1302的Sclk时钟线位定义
sbit ds1302_io = P2^4;    //DS1302的i/o数据线位定义
sbit ds1302_ce = P1^6;   //DS1302的ce片选线位定义
sbit ds = P2^2;          //DS18B20的数据引脚位定义
sbit fm = P2^3;	      //蜂鸣器位定义

sbit rd=P3^7;
sbit dula=P2^6;       //数码管段选
sbit wela=P2^7;      //数码管位选
sbit lcd1602_rs = P3^5; 	 //位定义1602液晶数据命令选择端
sbit lcd1602_rw = P3^6;		 //位定义1602液晶读写选择端
sbit lcd1602_en  = P3^4; 	 //位定义1602液晶使能端
sbit set = P3^0;	       //定义S9按键_时间设置选择键
sbit up  = P3^1;	       //定义S13按键_增加键
sbit down= P3^2;	       //定义S17按键_减小键
sbit nao = P3^3;          //定义S21按键_闹钟设置选择键

/************************* 2个延时函数 **************************/
void delay(uchar x)
{
	uchar y,z;
	for(z=x;z>0;z--)
		for(y=110;y>0;y--);
}

void delayus(uint t)   //微秒级的延时函数
{
	while(t--);
}

/********************* 与ds18b20相关函数 **********************/

void ds18b20_reset()      //DS18B20初始化
{
	ds=1;           
	delayus(5);      
	ds=0;          
	delayus(80);    
	ds=1;          
	delayus(14);    
	if(ds==0)             
		ds18b20_flag=1;    //ds18b20_flag等于1表示DS18B20存在
	else
		ds18b20_flag=0;    //ds18b20_flag等于0表示DS18B20不存在
	delayus(20);
}

bit ds_read_bit()    //读时隙（即位读取）函数
{
	bit dat;        
	ds=0;          
	_nop_();       
	_nop_();       
	ds=1;         
	_nop_();      
	dat=ds;       
	delayus(10);   
	return dat;    
}

void ds_write_ds1302_byte(uchar dat)   //DS18B20写一字节
{
	uchar i;
	for(i=0;i<8;i++)      //循环8次
	{
		ds=0;          
		_nop_();        
		ds=dat&0x01;    //dat写0x01按位与，目的是先传送dat的最低位
		delayus(6);      
		ds=1;          
		dat=dat>>1;     //让dat右移一位，准备下一位的写入
	}
	delayus(6);     
}

uchar ds_read_byte()	//DS18B20读一字节
{
	uchar i,j,k;
	for(i=0;i<8;i++)   //循环8次
	{
		j=ds_read_bit();   //读到的位值赋给j
	    k=(j<<7)|(k>>1);  
	}
	return k;  //把读到的值k返回
}

uint read_temperature()    //DS18B20读温度           
{
	uchar a,b;
	ds18b20_reset();        //单总线初始化
	ds_write_ds1302_byte(0xcc);    // 跳过读序号列号的操作
	ds_write_ds1302_byte(0x44);    // 启动温度转换
	delayus(150); 
	ds18b20_reset();       //单总线初始化
	ds_write_ds1302_byte(0xcc);  //发送跳过ROM指令，板上只接一个DS18B20，不需匹配
	ds_write_ds1302_byte(0xbe);   //读取温度值，即读暂存器（代码为BEH）
	delayus(150); 
	a=ds_read_byte();    //调用读一个字节的函数,把读到的低8位赋值给a
	b=ds_read_byte();    //把读到的低8位赋值给b
	temp=b;
	temp=temp<<8;
	temp=temp|a;      //把高8位b和低8位a，组成16位数据赋给temp保存
	temp=temp*0.0625*10+0.5;  
	return temp;    //把temp值返回
}

/************************与ds1302相关函数**************************/

void write_ds1302_byte(uchar dat)   //ds1302写一字节
{
	uchar i;
	for(i=0;i<8;i++)   //分8次循环，把（add）一位一位的写入
	{
		ds1302_sclk=0;	
		ds1302_io =dat&0x01;   //dat和0x01进行按位与，保留最低位。即从低位开始写入
		dat=dat>>1;   //add右移一位
		ds1302_sclk=1; 
	}
}

void ds1302_write(uchar add,uchar date)  //单字节写操作函数（包含地址和数据）
{
	ds1302_ce=0;      
	ds1302_sclk=0;     
	ds1302_ce=1;    //ce变为高电平，允许单片机向DS1302中的寄存器写入地址命令和数据
	_nop_();         
	write_ds1302_byte(add);  //写入控制命令，（指明写入的寄存器地址及后续为写操作）
	write_ds1302_byte(date);   //写入一个字节数据
	ds1302_ce=0;     //地址命令和数据写完之后，把ce拉低，防止对写入的数据进行误操作
	_nop_();         
	ds1302_io =1;    //释放IO数据线
	ds1302_sclk=1;   //释放sclk时钟线
}
 
uchar ds1302_read(uchar add)  //单字节读操作函数
{
	uchar i,value;
	ds1302_ce=0;     
	ds1302_sclk=0;    
	ds1302_ce=1;  //ce变为高电平，单片机向DS1302中的寄存器写入地址命令，并读出数据
	_nop_();      //稍微延时（一个机器周期）
	write_ds1302_byte(add);  //写入控制命令，（指明要读取的寄存器地址及后续为读操作）
	for(i=0;i<8;i++)   //分8次循环，把数据一位一位的读出
	{
		value=value>>1;     //value右移一位
			ds1302_sclk=0;    //把sclk时钟置为低电平，开始读取数据
		if(ds1302_io)
		{
			value=value|0x80;    //把I0读到的值，放到value 的最高位
		}
		ds1302_sclk=1; 
	}
	ds1302_ce=0;      //一个字节的数据读完之后，把ce拉低
	_nop_();
	ds1302_sclk=0;     //释放sclk时钟线
	_nop_();
	ds1302_sclk=1;
	ds1302_io=1;      //释放io数据线
	return value;    //把 value值返回
}

void set_rtc()           //ds1302时间初始化函数                
{
	ds1302_ce=0;
	ds1302_sclk=1; 
	ds1302_write(0x8e,0x00);		//写允许	
	ds1302_write(0x80,0x58);        //秒设置  
	ds1302_write(0x82,0x56);        //分设置
	ds1302_write(0x84,0x23);        //时设置
	ds1302_write(0x86,0x21);        //日设置
	ds1302_write(0x88,0x12);        //月设置
	ds1302_write(0x8a,0x02);        //周设置
	ds1302_write(0x8c,0x10);        //年设置
	ds1302_write(0x90,0xa5);        //充电
	ds1302_write(0x8e,0x80);	    //写保护		    
}

/***************************与lcd1602相关函数***************************/

void lcd_write_com(uchar com)   //写命令函数
{
	lcd1602_rs=0;     //数据命令选择端，写命令时设为0
	lcd1602_rw=0;    //读写选择端，写时设为0
	lcd1602_en=0;  
	P0=com;        //将要写的命令送到数据总线上
	lcd1602_en=1;   //使能端电平变换，形成一个高脉冲将命令写入到液晶控制器
	delay(5);        //延时
	lcd1602_en=0;		
}

void lcd_write_date(uchar date)    //写数据函数
{
    lcd1602_rs=1;      //数据命令选择端，写数据时设为1
	lcd1602_rw=0;     //读写选择端，写时设为0
	lcd1602_en=0;
	P0=date;       //将要写的数据送到数据总线上
	lcd1602_en=1;  //使能端电平变换，形成一个高脉冲将命令写入到液晶控制器
	delay(5);       //延时
	lcd1602_en=0;	
}

void lcd1602_init()	         //LCD1602初始化函数	
{
	uchar lcdnum;
	lcd_write_com(0x38);
	lcd_write_com(0x0c);
	lcd_write_com(0x06);
	lcd_write_com(0x01);
	lcd_write_com(0x80);              //写第一行数据
	for(lcdnum=0;lcdnum<8;lcdnum++)	       
	{
		lcd_write_date(table1[lcdnum]);
		delay(2);
	}
	lcd_write_com(0x80+0x40);		    //写第二行数据 
	for(lcdnum=0;lcdnum<13;lcdnum++)
	{
		lcd_write_date(table2[lcdnum]);
		delay(2);
	}
}

/*******************************显示部分********************************/

void write_time1(uchar add,uchar date)    //日期送显示
{	
	uchar shi,ge;
	shi=date/10;
	ge=date%10;
	lcd_write_com(0x80+add);
	lcd_write_date(0x30+shi);
	lcd_write_date(0x30+ge);
}

void write_time2(uchar add,uchar date)    //时间送显示
{	
	uchar shi,ge;
	shi=date/10;
	ge=date%10;
	lcd_write_com(0x80+0x40+add);
	lcd_write_date(0x30+shi);
	lcd_write_date(0x30+ge);
}

uchar bcd_decimal(uchar bcd)        //bcd转换十进制
{
	uchar decimal;
	decimal=bcd>>4;
	decimal=decimal*10+(bcd&=0x0f);
	return decimal; 	
}

void wendu_decimal(uint dat)        //温度转换后送LCD1602显示
{                    
	wendu_shi=dat/100;               //取十位 
	wendu_ge =dat%100/10;            //取个位  
	wendu_shu=dat%100%10;          //取小数
	lcd_write_com(0x80+0x40+10);     //送显示
	lcd_write_date(0x30+wendu_shi);
	lcd_write_date(0x30+wendu_ge);
	lcd_write_date(0x2e);  
	lcd_write_date(0x30+wendu_shu);
	lcd_write_date(0xdf);           //温度符号
	lcd_write_date(0x43);	
}

void write_week(uchar we)        //星期送显示
{
	lcd_write_com(0x80+0x0d);
	switch(we)
	{
		case 1: lcd_write_date('M');
				lcd_write_date('0');
		 		lcd_write_date('N');
		 		break;
		case 2: lcd_write_date('T');
				lcd_write_date('U');
		 		lcd_write_date('E');
		 		break;
		case 3: lcd_write_date('W');
				lcd_write_date('E');
		 		lcd_write_date('D');
		 		break;
		case 4: lcd_write_date('T');
				lcd_write_date('H');
		 		lcd_write_date('U');
		 		break;	
		case 5: lcd_write_date('F');
				lcd_write_date('R');
		 		lcd_write_date('T');
		 		break;
		case 6: lcd_write_date('S');
				lcd_write_date('A');
		 		lcd_write_date('T');
		 		break;
		case 7: lcd_write_date('S');
				lcd_write_date('U');
		 		lcd_write_date('N');
		 		break;		 					 				 		
	}	
}

/******************************按键处理******************************/

uchar key_bcd(uchar key_decimal)    //转成ds1302所需的BCD码 
{
	uchar temp;
	temp=(((key_decimal/10)&0x0f)<<4)|(key_decimal%10);
	return temp;	
}

void key_up_down()     //加减键处理函数
{
	if(up==0)   //加键处理
	{
		delay(50);
		flag_up=1;     //"加"更新标志位
		while(!up);
		switch(count)
		{
			case 1:
					miao++;
					if(miao>59)
						miao=0;
					break;
			case 2:
					fen++;
					if(fen>59)
						fen=0;
					break;
			case 3:
					shi++;
					if(shi>23)
						shi=0;
					break;				
			case 4:
					week++;
					if(week>7)
						week=1;
					break;				
			case 5:
					ri++;
					if(ri>31)
						ri=1;
					break;					
			case 6:
					yue++;
					if(yue>12)
						yue=1;
					break;					
			case 7:	
					nian++;
					if(nian>99)
						nian=0;
					break;												
		}
	}
	if(down==0)    //减键处理
	{
		delay(50);
		flag_down=1;	   //"减"更新标志位			
		while(!down);
		switch(count)
		{
			case 1:
					miao--;
					if(miao==255)
						miao=59;
					break;
			case 2:
					fen--;
					if(fen==255)
						fen=59;
					break;
			case 3:
					shi--;
					if(miao==255)
						shi=23;
					break;				
			case 4:
					week--;
					if(week<1)
						week=7;
					break;				
			case 5:
					ri--;
					if(ri<1)
						ri=31;
					break;					
			case 6:
					yue--;
					if(yue<1)
						yue=12;
					break;					
			case 7:	
					nian--;
					if(nian==255)
						nian=99;
					break;												
		}
	}			
}

/************************* at24c02处理函数****************************/

void alarm_ring()   
{
	if(alarm_on==1)		//alarm_on=1为闹钟有效
	{
		if(shi==alarm_shi && fen==alarm_fen && miao==alarm_miao) 
		flag_alarm=1;      //闹钟时间到，闹钟标志位置1
	}						
	if(flag_alarm==1)
	{
		uchar i,j,t;
		t=30;
		for(i=0;i<200;i++)
		{
	 	fm=~fm;      //蜂鸣器响
		for(j=0;j<t;j++);
		}
		
		if(set==0 || up==0 || down==0 || nao==0)    //闹钟响时，按任意键取消闹钟
		{
			delay(50); //延时
			if(set==0 || up==0 || down==0 || nao==0)  //再次确认是否有任意键按下
			{
				while(!set);
				while(!up);
				while(!down);
				while(!nao);
				flag_alarm=0;
				fm=1;       //蜂鸣器停止响
			}
		}		
	}	
}

void c02_init()   //AT24C02初始化函数
{
	c_init();
	alarm_shi=c02_read_add(1);		//读取闹钟_时
	delay(200);
	alarm_fen=c02_read_add(2);		//读取闹钟_分
	delay(200);
	alarm_miao=c02_read_add(3);	//读取闹钟_秒
	delay(200);
	alarm_on =c02_read_add(4);    //读取闹钟开关值，为0关，为1开	
	delay(200);	
}

void alarm_huan()     //闹钟设置界面
{
	uchar num;
	lcd_write_com(0x01);
	lcd_write_com(0x80);
	for(num=0;num<10;num++)	   //写第一行数据 
	{
		lcd_write_date(table3[num]);
		delay(2);
	}
	lcd_write_com(0x0F);      //显示光标并闪烁
	write_time2(4,alarm_shi);
	lcd_write_date(0x3a);
	write_time2(7,alarm_fen);
	lcd_write_date(0x3a);
	write_time2(10,alarm_miao);
	if(alarm_on==0)
	{
		lcd_write_com(0x80+0x40+13);
		lcd_write_date('O');
		lcd_write_date('F');
		lcd_write_date('F');	
	}
	if(alarm_on==1)
	{
		lcd_write_com(0x80+0x40+13);
		lcd_write_date(' ');
		lcd_write_date('O');
		lcd_write_date('N');
	}	 
}

void key_set_alarm()   //时间设置键ste和闹钟设置键nao扫描函数
{
	if(set==0 && alarm_count==0 && flag_alarm==0)
	{
		delay(50);
		if(set==0)
		{	
			while(!set);       //等待set键释放
			count++;          //按set一下，count加1，进入时间调速扫描程序  
			lcd_write_com(0x0f);  //把1602液晶显示光标并闪烁
			if(flag==1)
				{
					done=1;
					flag=0;
					ds1302_write(0x8e,0x00);	//写允许	
					ds1302_write(0x80,key_bcd(miao)|0x80); //BIT7为1，晶振停止工作
					ds1302_write(0x8e,0x80);     //写保护	
				}		
		}
	}
	if(nao==0 && count==0 && flag_alarm==0)
	{
		delay(50);
		if(nao==0)  
		{
			while(!nao);    //等待nao键释放
			alarm_count++;
			if(flag==1)
			{	
				done=1;
				flag=0;
				alarm_huan();    //进入闹钟设置界面
			}
		}
	}						
}

void keyjpress()	//按键处理
{	
	key_set_alarm();
	if(count!=0)      //count不为0，进入时间调整扫描
	{
			
		switch(count)
		{
			case 1:do
				   {
						lcd_write_com(0x80+0x40+7);    //调整秒
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;
							flag_down=0;
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x80,key_bcd(miao) | 0x80);
							ds1302_write(0x8e,0x80);        
	    					write_time2(6,miao);
	    					lcd_write_com(0x80+0x40+7);  //液晶写字符后光标自动
                                                       //向右移动一位，把光标
                                                       //左移一位
	    				}
	    		   }
	    			while(count==2);
					break;
			case 2:do
				   {
						lcd_write_com(0x80+0x40+4);     //调整分
						key_up_down();						
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x82,key_bcd(fen));
							ds1302_write(0x8e,0x80);        
	    					write_time2(3,fen);
	    					lcd_write_com(0x80+0x40+4);
	    				}	
	    			}
	    			while(count==3);	
					break;
			case 3:do
				   {	
						lcd_write_com(0x80+0x40+1);     //调整时
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x84,key_bcd(shi));
							ds1302_write(0x8e,0x80);        
	    					write_time2(0,shi);
	    					lcd_write_com(0x80+0x40+1);
	    				}
	    			}
	    			while(count==4);
					break;			
			case 4: do
				   {
						lcd_write_com(0x80+0x0e);    //调整星期
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;						
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x8a,key_bcd(week));
							ds1302_write(0x8e,0x80);        
	    					write_week(week);
	    					lcd_write_com(0x80+0x0e);
	    				}	
	    			}
	    			while(count==5);
					break;			
			case 5:do
				   {	
						lcd_write_com(0x80+9);     //调整日
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x86,key_bcd(ri));
							ds1302_write(0x8e,0x80);        
	    					write_time1(8,ri);
	    					lcd_write_com(0x80+9);
	    				}
	    			}
					while(count==6);
					break;			
			case 6:do
				   {		    
						lcd_write_com(0x80+6);     //调整月
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;						
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x88,key_bcd(yue));
							ds1302_write(0x8e,0x80);        
	    					write_time1(5,yue);
	    					lcd_write_com(0x80+6);
	    				}
	    			}
	    			while(count==7);
					break;			
			case 7:
						lcd_write_com(0x80+3);     //调整年
						key_up_down();
						if(flag_up || flag_down)
						{	
							flag_up=0;				   	
							flag_down=0;
							ds1302_write(0x8e,0x00);			
							ds1302_write(0x8c,key_bcd(nian));
							ds1302_write(0x8e,0x80);        
	    					write_time1(2,nian);
	    					lcd_write_com(0x80+3);
	    				}
	    			break;
			case 8:	
					lcd_write_com(0x0c);	 //调整结束，关闭显示光标
			 		flag=1;
			 		done=0;
					count=0;
					ds1302_write(0x8e,0x00);			
					ds1302_write(0x80,key_bcd(miao)&0x7f); //BIT7为0,晶振开始工作
					ds1302_write(0x8e,0x80); 
					break;	    						
			default:break;											
		}	
	}
	if(alarm_count!=0)	   //闹钟按键扫描
	{				
		switch(alarm_count)
		{
			case 1:
					lcd_write_com(0x80+0x40+15);
					if(up==0)
					{		
						delay(50);
						if(up==0)                     
						{
							while(!up); 
							alarm_on=1;	                 //开闹钟
							lcd_write_com(0x80+0x40+13);
							lcd_write_date(' ');
							lcd_write_date('O');
							lcd_write_date('N');
							c02_write_add(4,alarm_on);
							delay(200);
							lcd_write_com(0x80+0x40+15);
						}
					}
					if(down==0)
					{		
						if(down==0);                  
						{	
							while(!down);
							alarm_on=0;	                 //关闹钟
							lcd_write_com(0x80+0x40+13);
							lcd_write_date('O');
							lcd_write_date('F');
							lcd_write_date('F');
							c02_write_add(4,alarm_on);
							delay(200);
							lcd_write_com(0x80+0x40+15);
						}
					}					
					break;	
			case 2:
					lcd_write_com(0x80+0x40+11);        //闹钟秒设置
					if(up==0 || down==0)
					{	
						delay(50);
						if(up==0)
						{	
							while(!up);
							alarm_miao++;
							if(alarm_miao>59)
								alarm_miao=0;							
						}	
						if(down==0)
						{
							while(!down);
							alarm_miao--;
							if(alarm_miao==255)
								alarm_miao=59;							
						}
						write_time2(10,alarm_miao);
						lcd_write_com(0x80+0x40+11);
						c02_write_add(3,alarm_miao);
						delay(200);									
					}	
					break;						
			case 3:
					lcd_write_com(0x80+0x40+8);    //闹钟分设置
					if(up==0 || down==0)
					{	
						delay(50);
						if(up==0)
						{	
							while(!up);
							alarm_fen++;
							if(alarm_fen>59)
								alarm_fen=0;								
						}	
						if(down==0)
						{
							while(!down);
							alarm_fen--;
							if(alarm_fen==255)
								alarm_fen=59;								
						}
						write_time2(7,alarm_fen);
						lcd_write_com(0x80+0x40+8);
						c02_write_add(2,alarm_fen);
						delay(200);									
					}	
					break;

			case 4:
					lcd_write_com(0x80+0x40+5);    //闹钟时设置
					if(up==0 || down==0)
					{	
						delay(50);
						if(up==0)
						{	
							while(!up);
							alarm_shi++;
							if(alarm_shi>23)
								alarm_shi=0;								
						}	
						if(down==0)
						{
							while(!down);
							alarm_shi--;
							if(alarm_shi==255)
							alarm_shi=23;								
						}
						write_time2(4,alarm_shi);
						lcd_write_com(0x80+0x40+5);
						c02_write_add(1,alarm_shi);
						delay(200);									
					}					
					break;
			case 5:
					alarm_count=0;    //退出闹钟设置
					lcd1602_init();	
					flag=1;
					done=0;
					break;							
		}
	}		
}

void xianshi()   //1602显示函数
{
   //读秒分时，日月年，星期		
	miao=bcd_decimal(ds1302_read(0x81));  
	fen =bcd_decimal(ds1302_read(0x83));
	shi =bcd_decimal(ds1302_read(0x85));
	ri  =bcd_decimal(ds1302_read(0x87));
	yue =bcd_decimal(ds1302_read(0x89));
	nian=bcd_decimal(ds1302_read(0x8d));
	week=bcd_decimal(ds1302_read(0x8b));
   //送液晶显示		
	write_time2(6,miao);
	write_time2(3,fen);
	write_time2(0,shi);
	write_time1(8,ri);
	write_time1(5,yue);
	write_time1(2,nian);
	write_week(week);	
  //读温度	
	wendu=read_temperature(); 
  //温度显示
	wendu_decimal(wendu);
}

main()  //主函数
{
	uchar ch;  
	lcd1602_en=0;  //关闭1602液晶使能，防止1602数据端影响单片机P0口输出
	wela=1;
	P0=0xff;
	wela=0;         //关闭数码管位选，防止操作1602液晶时数码管出现乱码
	rd=0;           //把矩阵按键第4列一端置低，以分解出4个独立按键
	lcd1602_init();    //1602液晶初始化
	ds18b20_reset();  //18B20温度传器初始化
	c02_init();       //AT24C02初始化
	ch=ds1302_read(0x81)>>7;  //读取DS1302时钟的秒寄存器的值，并保留最高位
	if(ch)   //判断：若ch为0，不设置初值；若ch为1，重新设置初值
	{
	set_rtc();   //对DS1302设置时间初值
	}
	while(1)
	{
		if(done==1)
		{	
			keyjpress();
		}
		if(done==0)
		{
			xianshi();        //取得并显示日历、时间、温度
			key_set_alarm();
			alarm_ring();
		}				
	}
}  