单片机STC89C51控制继电器2秒吸合后2秒断开

2 阅读22分钟

下面的C语言程序单片机STC89C51控制继电器2秒吸合,2秒断开,程序使用KEILL3开发。 #include<reg52.h> //包含单片机寄存器的头文件 #include<intrins.h> //包含_nop_()函数定义的头文件 unsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字 //2013年9月26日,修正DS1302 干扰P1口LED灯问题 sbit SCLK=P1^7; //位定义1302芯片的接口,时钟输出端口定义在P1.7引脚 sbit DATA=P2^7; //位定义1302芯片的接口,数据输出端定义在P2.7引脚 sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.2引脚 sbit cs88=P2^2; sbit DU = P2^0; sbit WE = P2^1;

#define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写入操作,0xa1即为1010 0000B sbit SDA=P1^2; //将串行数据总线SDA位定义在为P1.2引脚 HL-1 接在P2.0 sbit SCL=P1^7; //将串行时钟总线SCL位定义在为P1.7引脚 HL-1 接在P2.1

//sbit SDA=P3^4; //将串行数据总线SDA位定义在为P1.2引脚 HL-1 接在P2.0 //sbit SCL=P3^3; //将串行时钟总线SCL位定义在为P1.7引脚 HL-1 接在P2.1 void Delay_ms(unsigned int uiMs); //ms延时函数,12M晶振有效

sbit sw = P1^4; //引脚定义 // sbit sw = P2^3; //引脚定义

unsigned char scan_key(); void proc_key(unsigned char key_v); void delayms(unsigned char ms); unsigned char key_s,key_v; sbit K1 = P3^6; sbit K2 = P3^5; unsigned char scan_key() { unsigned char key_s; key_s = 0x00; key_s |= K2; key_s <<= 1; key_s |= K1;

// key_s = 0x00; // key_s |= K2; // key_s = 0x00; // key_s |= K1; return key_s; } /***************************************************** 函数功能:延时若干微秒 入口参数:n ***************************************************/ void delaynus(unsigned char n) { unsigned char i; for(i=0;i<n;i++); }

void cmg88()//关数码管,点阵函数 { DU=1;
P0=0X00; DU=0; }

void delayms(unsigned char ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } }

/***************************************************** 函数功能:向1302写一个字节数据 入口参数:x ***************************************************/ void Write1302(unsigned char dat) { unsigned char i; SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delaynus(2); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续写8个二进制位数据 { DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后 delaynus(2); //稍微等待,使硬件做好准备 SCLK=1; //上升沿写入数据 delaynus(2); //稍微等待,使硬件做好准备 SCLK=0; //重新拉低SCLK,形成脉冲 dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位 }

} /***************************************************** 函数功能:根据命令字,向1302写一个字节数据 入口参数:Cmd,储存命令字;dat,储存待写的数据 / void WriteSet1302(unsigned char Cmd,unsigned char dat) { RST=0; //禁止数据传递 SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 delaynus(2); //稍微等待,使硬件做好准备 Write1302(Cmd); //写入命令字 Write1302(dat); //写数据 SCLK=1; //将时钟电平置于高电平状态 RST=0; //禁止数据传递 } /** 函数功能:从1302读一个字节数据 入口参数:x / unsigned char Read1302(void) { unsigned char i,dat; delaynus(2); //稍微等待,使硬件做好准备 for(i=0;i<8;i++) //连续读8个二进制位数据 { dat>>=1; if(DATA==1) //如果读出的数据是1 dat|=0x80; //将1取出,写在dat的最高位 SCLK=1; //将SCLK置于高电平,为下降沿读出 delaynus(2); //稍微等待 SCLK=0; //拉低SCLK,形成脉冲下降沿 delaynus(2); //稍微等待 } return dat; //将读出的数据返回 }
/
** 函数功能:根据命令字,从1302读取一个字节数据 入口参数:Cmd / unsigned char ReadSet1302(unsigned char Cmd) { unsigned char dat; RST=0; //拉低RST SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 Write1302(Cmd); //写入命令字 dat=Read1302(); //读出数据 SCLK=1; //将时钟电平置于已知状态 RST=0; //禁止数据传递 return dat; //将读出的数据返回 } /** 函数功能: 1302进行初始化设置 ***************************************************/ void Init_DS1302(void) { unsigned char flag;

flag= ReadSet1302(0x81);
if(flag&0x80)	{      //判断时钟芯片是否关闭
 WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令 
WriteSet1302(0x80,((55/10)<<4|(55%10)));   //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10)));   //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((9/10)<<4|(9%10)));  //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5);                //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80);			   //根据写状态寄存器命令字,写入保护指令

}

} //如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话 就用上面的语句

/--------------------这是每次都初始化的语句-----------------/ /* WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令 WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值

WriteSet1302(0x82,((59/10)<<4|(59%10)));   //根据写分寄存器命令字,写入分的初始值

WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值

WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((9/10)<<4|(9%10)));   //根据写年寄存器命令字,写入年的初始值

WriteSet1302(0x90,0xa5);                //打开充电功能 选择2K电阻充电方式

WriteSet1302(0x8E,0x80);              //根据写状态寄存器命令字,写入保护指令

*/										

/******************************************************************************* 以下是对液晶模块的操作程序 ***************/ sbit RS=P1^0; //寄存器选择位,将RS位定义为P1.0引脚 sbit RW=P1^1; //读写选择位,将RW位定义为P1.1引脚 sbit E=P2^5; //使能信号位,将E位定义为P2.5引脚 sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚 / 函数功能:延时1ms (3j+2)i=(3×33+2)×10=1010(微秒),可以认为是1毫秒 / void delay1ms() { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<33;j++) ; } / 函数功能:延时若干毫秒 入口参数:n / void delaynms(unsigned char n) { unsigned char i; for(i=0;i<n;i++) delay1ms(); } / 函数功能:判断液晶模块的忙碌状态 返回值:result。result=1,忙碌;result=0,不忙 / bit BusyTest(void) { bit result; RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; //E=1,才允许读写 nop(); //空操作 nop(); nop(); nop(); //空操作四个机器周期,给硬件反应时间 result=BF; //将忙碌标志电平赋给result E=0; //将E恢复低电平 return result; } / 函数功能:将模式设置指令或显示地址写入液晶模块 入口参数:dictate / void WriteInstruction (unsigned char dictate) {
while(BusyTest()==1); //如果忙就等待 RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0;
E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" nop(); nop(); //空操作两个机器周期,给硬件反应时间 P0=dictate; //将数据送入P0口,即写入指令或地址 nop(); nop(); nop(); nop(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 nop(); nop(); nop(); nop(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /
函数功能:指定字符显示的实际地址 入口参数:x / void WriteAddress(unsigned char x) { WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x" } /
函数功能:将数据(字符的标准ASCII码)写入液晶模块 入口参数:y(为字符常量) / void WriteData(unsigned char y) { while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" P0=y; //将数据送入P0口,即将数据写入液晶模块 nop(); nop(); nop(); nop(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 nop(); nop(); nop(); nop(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /
函数功能:对LCD的显示模式进行初始化设置 ***************************************************/ void LcdInitiate(void) { delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口 delaynms(5); //延时5ms ,给硬件一点反应时间 WriteInstruction(0x38); delaynms(5); //延时5ms ,给硬件一点反应时间 WriteInstruction(0x38); //连续三次,确保初始化成功 delaynms(5); //延时5ms ,给硬件一点反应时间 WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁 delaynms(5); //延时5ms ,给硬件一点反应时间 WriteInstruction(0x06); //显示模式设置:光标右移,字符不移 delaynms(5); //延时5ms ,给硬件一点反应时间 WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除 delaynms(5); //延时5ms ,给硬件一点反应时间

} /************************************************************** 以下是1302数据的显示程序 *********/ / 函数功能:显示秒 入口参数:x ***************************************************/ void DisplaySecond(unsigned char x) { unsigned char i,j; //j,k分别储存十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x49); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将百位数字的字符常量写入LCD WriteData(digit[j]); //将十位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
}

/***************************************************** 函数功能:显示分钟 入口参数:x / void DisplayMinute(unsigned char x) { unsigned char i,j; //j,k十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将百位数字的字符常量写入LCD WriteData(digit[j]); //将十位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
} /
** 函数功能:显示小时 入口参数:x / void DisplayHour(unsigned char x) { unsigned char i,j; //j,k十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x43); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将百位数字的字符常量写入LCD WriteData(digit[j]); //将十位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
} /
** 函数功能:显示日 入口参数:x / void DisplayDay(unsigned char x) { unsigned char i,j; //j,k十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x0c); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将十位数字的字符常量写入LCD WriteData(digit[j]); //将个位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
} /
** 函数功能:显示月 入口参数:x / void DisplayMonth(unsigned char x) { unsigned char i,j; //j,k分别储存十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x09); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将十位位数字的字符常量写入LCD WriteData(digit[j]); //将个位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
} /
** 函数功能:显示年 入口参数:x ***************************************************/ void DisplayYear(unsigned char x) { unsigned char i,j; //j,k分别储存十位和个位 i=x/10;//取十位 j=x%10;//取个位
WriteAddress(0x06); //写显示地址,将在第2行第7列开始显示 WriteData(digit[i]); //将十位位数字的字符常量写入LCD WriteData(digit[j]); //将个位数字的字符常量写入LCD delaynms(50); //延时1ms给硬件一点反应时间
}

/***************************************************** 函数功能:延时1ms ***************************************************/ //void delay1ms() //{ // unsigned char i,j; // for(i=0;i<10;i++) // for(j=0;j<33;j++) // ; // }

/***************************************************** 函数功能:延时若干毫秒 入口参数:n / // void delaynms(unsigned char n) // { // unsigned char i; // for(i=0;i<n;i++) // delay1ms(); // } / 函数功能:开始数据传送 / void start() // 开始位 { SDA = 1; //SDA初始化为高电平“1” SCL = 1; //开始数据传送时,要求SCL为高电平“1” nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 SDA = 0; //SDA的下降沿被认为是开始信号 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
} /
函数功能:结束数据传送 / void stop() // 停止位 { SDA = 0; //SDA初始化为低电平“0” _n SCL = 1; //结束数据传送时,要求SCL为高电平“1” nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 SDA = 1; //SDA的上升沿被认为是结束信号 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 nop(); //等待一个机器周期 SDA=0; SCL=0; } / 函数功能:从AT24Cxx读取数据 出口参数:x / unsigned char ReadData() // 从AT24Cxx移入数据到MCU { unsigned char i; unsigned char x; //储存从AT24Cxx中读出的数据 for(i = 0; i < 8; i++) { SCL = 1; //SCL置为高电平 x<<=1; //将x中的各二进位向左移一位 x|=(unsigned char)SDA; //将SDA上的数据通过按位“或“运算存入x中 SCL = 0; //在SCL的下降沿读出数据 } return(x); //将读取的数据返回 } / 函数功能:向AT24Cxx的当前地址写入数据 入口参数:y (储存待写入的数据) ***************************************************/ //在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0 bit WriteCurrent(unsigned char y) { unsigned char i; bit ack_bit; //储存应答位 for(i = 0; i < 8; i++) // 循环移入8个位 { SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S //因为传送时高位在前,低位在后 nop(); //等待一个机器周期
SCL = 1; //在SCL的上升沿将数据写入AT24Cxx
nop(); //等待一个机器周期 nop(); //等待一个机器周期

  	SCL = 0;            //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲
	y <<= 1;           //将y中的各二进位向左移一位
}
SDA = 1;			  // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线,
                //以让SDA线转由接收设备(AT24Cxx)控制
_nop_();        //等待一个机器周期 
_nop_();        //等待一个机器周期 
SCL = 1;       //根据上述规定,SCL应为高电平
_nop_();       //等待一个机器周期 
_nop_();       //等待一个机器周期 
_nop_();       //等待一个机器周期 
_nop_();       //等待一个机器周期 
ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节
               //若送高电平,表示没有接收到,传送异常
SCL = 0;       //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递)
return  ack_bit;			// 返回AT24Cxx应答位

} /*************************************************** 函数功能:向AT24Cxx中的指定地址写入数据 入口参数:add (储存指定的地址);dat(储存待写入的数据) / void WriteSet(unsigned char add, unsigned char dat) // 在指定地址addr处写入数据WriteCurrent { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(add); //写入指定地址 WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据 stop(); //停止数据传递 delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上 } / 函数功能:从AT24Cxx中的当前地址读取数据 出口参数:x (储存读出的数据) / unsigned char ReadCurrent() { unsigned char x; start(); //开始数据传递 WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据 x=ReadData(); //将读取的数据存入x stop(); //停止数据传递 return x; //返回读取的数据 } / 函数功能:从AT24Cxx中的指定地址读取数据 入口参数:set_addr 出口参数:x ***************************************************/ unsigned char ReadSet(unsigned char set_addr) // 在指定地址读取 { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(set_addr); //写入指定地址 return(ReadCurrent()); //从指定地址读出数据并返回 } void proc_key(unsigned char key_v) { unsigned char second,minute,hour,day,month,year; //分别储存秒、分、小时,日,月,年 unsigned char ReadValue; //储存从1302读取的数据 unsigned char ReadValue1,ReadValue2; //储存从1302读取的数据 unsigned char minute1,minute2,shuju,shuju1,shuju2; //储存从1302读取的数据 unsigned int i; if((key_v & 0x01) == 0) { // P0 = cror(P0,1); anjian: for(i=0;i<6;i++)// 设置继电器吸合时间为4s {

  ReadValue = ReadSet1302(0x81);   //从秒寄存器读数据

// WriteSet(0x01,ReadValue); //写入显示代码到AT24C02 second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化

  DisplaySecond(second);          //显示秒
  ReadValue = ReadSet1302(0x83);  //从分寄存器读
 minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayMinute(minute);	       //显示分
 ReadValue = ReadSet1302(0x85);  //从时寄存器读
 hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayHour(hour);	             //显示小时
 ReadValue = ReadSet1302(0x87);  //从日寄存器读
 day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayDay(day);                //显示日
  ReadValue = ReadSet1302(0x89);  //从月寄存器读
 month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayMonth(month);            //显示月
  ReadValue = ReadSet1302(0x8d);  //从年寄存器读
 year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayYear(year);              //显示年
					     ReadValue1 = ReadSet1302(0x81);  //从分寄存器读
 minute1=((ReadValue1&0x70)>>4)*10 + (ReadValue1&0x0F); //将读出数据转化
	 WriteSet(0x01,minute1); //写入显示代码到AT24C02 
	 //	 WriteSet(0x01,ReadValue1); //写入显示代码到AT24C02 
	 	//	  Delay_ms(120);

		 }

    ReadValue2 = ReadSet1302(0x81);  //从分寄存器读
 minute2=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F); //将读出数据转化
  	 WriteSet(0x02,minute2); //写入显示代码到AT24C02 
	 //	 WriteSet(0x02,ReadValue2); //写入显示代码到AT24C02 	
//	   	  Delay_ms(120);

		 		 	 shuju = ReadSet(0x01);  //从AT24C02移出数据送到P1口显示 
		 shuju1 = ReadSet(0x02);  //从AT24C02移出数据送到P1口显示 
		 shuju2=ReadSet(0x01)-ReadSet(0x02);
		 
		 //shuju2=shuju1-shuju;
		 //if(shuju2=0x02)
		//   shuju2=3;
		  	 if(shuju2<6)
	//	  if(shuju2=2)
		 {
   		sw = 0;
//	Delay_ms(100);
	}
	else   	
	{
	sw = 1;
//	Delay_ms(100);

	}


		for(i=0;i<6;i++) 
{

  ReadValue = ReadSet1302(0x81);   //从秒寄存器读数据

// WriteSet(0x01,ReadValue); //写入显示代码到AT24C02 second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化 DisplaySecond(second); //显示秒 ReadValue = ReadSet1302(0x83); //从分寄存器读 minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 DisplayMinute(minute); //显示分 ReadValue = ReadSet1302(0x85); //从时寄存器读 hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 DisplayHour(hour); //显示小时 ReadValue = ReadSet1302(0x87); //从日寄存器读 day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 DisplayDay(day); //显示日 ReadValue = ReadSet1302(0x89); //从月寄存器读 month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 DisplayMonth(month); //显示月 ReadValue = ReadSet1302(0x8d); //从年寄存器读 year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化 DisplayYear(year); //显示年 ReadValue1 = ReadSet1302(0x81); //从分寄存器读 minute1=((ReadValue1&0x70)>>4)*10 + (ReadValue1&0x0F); //将读出数据转化 WriteSet(0x01,minute1); //写入显示代码到AT24C02 // WriteSet(0x01,ReadValue1); //写入显示代码到AT24C02

	 	//	  Delay_ms(120);
		 }

    ReadValue2 = ReadSet1302(0x81);  //从分寄存器读
 minute2=((ReadValue2&0x70)>>4)*10 + (ReadValue2&0x0F); //将读出数据转化
  	 WriteSet(0x02,minute2); //写入显示代码到AT24C02 
	// 	 WriteSet(0x02,ReadValue2); //写入显示代码到AT24C02 	
//	   	  Delay_ms(120);

		 		 	 shuju = ReadSet(0x01);  //从AT24C02移出数据送到P1口显示 
		 shuju1 = ReadSet(0x02);  //从AT24C02移出数据送到P1口显示 
		 shuju2=ReadSet(0x01)-ReadSet(0x02);
	//	  	 shuju2=shuju1-shuju;

// if(shuju2=0x02) // shuju2=3; if(shuju2<6) // if(shuju2=2) { sw = 1; // Delay_ms(100); } else { sw = 0; // Delay_ms(100);

	}
}
  
else if((key_v & 0x02) == 0)
{
//	P0 = _crol_(P0, 1);
  ReadValue = ReadSet1302(0x81);   //从秒寄存器读数据

// WriteSet(0x01,ReadValue); //写入显示代码到AT24C02 second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化

  DisplaySecond(second);          //显示秒
  ReadValue = ReadSet1302(0x83);  //从分寄存器读
 minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayMinute(minute);	       //显示分
 ReadValue = ReadSet1302(0x85);  //从时寄存器读
 hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayHour(hour);	             //显示小时
 ReadValue = ReadSet1302(0x87);  //从日寄存器读
 day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayDay(day);                //显示日
  ReadValue = ReadSet1302(0x89);  //从月寄存器读
 month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayMonth(month);            //显示月
  ReadValue = ReadSet1302(0x8d);  //从年寄存器读
 year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  DisplayYear(year);              //显示年
					     ReadValue1 = ReadSet1302(0x81);  //从分寄存器读
 minute1=((ReadValue1&0x70)>>4)*10 + (ReadValue1&0x0F); //将读出数据转化
	  	sw = 1;
}
goto anjian;

}

/***************************************************** 函数功能:主函数 ***************************************************/ void main(void) {

// next: cmg88(); LcdInitiate(); //将液晶初始化 WriteAddress(0x01); //写Date的显示地址,将在第1行第2列开始显示 WriteData('D'); //将字符常量写入LCD WriteData('a'); //将字符常量写入LCD WriteData('t'); //将字符常量写入LCD WriteData('e'); //将字符常量写入LCD WriteData(':'); //将字符常量写入LCD WriteAddress(0x08); //写年月分隔符的显示地址, 显示在第1行第9列 WriteData('-'); //将字符常量写入LCD WriteAddress(0x0b); //写月日分隔符的显示地址, 显示在第1行第12列 WriteData('-'); //将字符常量写入LCD WriteAddress(0x45); //写小时与分钟分隔符的显示地址, 显示在第2行第6列 WriteData(':'); //将字符常量写入LCD WriteAddress(0x48); //写分钟与秒分隔符的显示地址, 显示在第2行第9列 WriteData(':'); //将字符常量写入LCD Init_DS1302(); //将1302初始化 SDA = 1; // SDA=1,SCL=1,使主从设备处于空闲状态 SCL = 1; key_v = 0x03; while(1) {

 	key_s = scan_key();
	if(key_s != key_v)
	{
		delayms(10);
		key_s = scan_key();
		if(key_s != key_v)
		{	
			key_v = key_s;
			proc_key(key_v);					
		}
	}


 }

}

void Delay_ms(unsigned int uiMs) //ms延时函数 { unsigned int i; for(;uiMs > 0;uiMs--) { for(i = 1498;i > 0;i--); } }