⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcf8563.c

📁 本源代码是一个51单片机控制pcf8563时钟日历芯片的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*---------------PCF8563修改历史----------------
   2008.5.4     添加启动停止函数
   2008.5.8     添加键值管理和识别函数
   2008.5.8     添加时间显示函数year_display()等
   2008.5.9     添加部分调节时间的代码
   2008.5.11 	添加闹钟显示部分
   2008.5.14    添加时钟关闭程序
-----------------------------------------------*/
#include <reg52.h>
#include <intrins.h>
#include "lcd.h"
#include "IIC.h"
#include "common.h"



//开始PCF8563T驱动程序

/*--------------------------------------------------------------------------------
 调用方式:void GetPCF8563(uchar firsttype,uchar count,uchar *buff) ﹫2001/08/0 7
 函数说明:读取时钟芯片PCF8563的时间,设置要读的第一个时间类型firsttype,并设置读取
 的字节数,则会一次把时间读取到buff中。顺序是:
 0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
 ---------------------------------------------------------------------------------*/
 void GetPCF8563(uchar firsttype,uchar count,uchar *buff)
 {
 uchar i;
 start();
 sendbyte(0xA2);
 WaitAck();
 sendbyte(firsttype);
 WaitAck();

 start();
 sendbyte(0xA3);
 WaitAck();

 for (i=0;i<count;i++)
 {
 buff[i]=receivebyte();
 if (i!=count-1) ack();//除最后一个字节外,其他都要从MASTER发应答。
 }
 n_ack();
 stop();
}



//---------------------------------------------------------------------------------
 //调用方式:void SetPCF8563(uchar timetype,uchar value) ﹫2001/08/0 7
 //函数说明:调整时钟。timetype是要改的时间类型,value是新设置的时间值(BCD格式)。
 //0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
//---------------------------------------------------------------------------------*/
void SetPCF8563(uchar timetype,uchar value)
{
 start();
 sendbyte(0xA2);
 WaitAck();
 sendbyte(timetype);
 WaitAck();
 sendbyte(value);
 WaitAck();
 stop();
}

//---------------------PCF8563启动停止函数------------------------------------------
void pcf8563start(void)
{
SetPCF8563(ctrl1,0x00);
}

void pcf8563stop(void)
{
SetPCF8563(ctrl1,0x20);
}
//---------------------PCF8563出始时间设定------------------------------------------
void setime(void)
{ 
   /*SetPCF8563(year,0x08);
   SetPCF8563(month,0x03);
   SetPCF8563(week,0x01);
   SetPCF8563(day,0x03);
   SetPCF8563(hour,0x12);
   SetPCF8563(minute,0x00);*/
   GetPCF8563(minute,6,rbuf);
   time_display(rbuf);
   return;
}
/********************* 键盘识别程序 **********************/
uint getch(void)
{   uchar X,Y,Z;
    uint k;
	P1=0xff;
	P1=0x0f;       //先对P3置数  行扫描
	if(P1!=0x0f)     //判断是否有键按下
	{delay(10);    //延时,软件去干扰
    if(P1!=0x0f)   //确认按键按下X = P3;
	{	
    X=P1;       //保存行扫描时有键按下时状态
	P1=0xf0;       //列扫描
	Y=P1;          //保存列扫描时有键按下时状态
 	Z=X|Y;         //取出键值
	
	switch ( Z )   //判断键值(那一个键按下)
	{
		case 0xee: k=13; break; //对键值赋值
		case 0xde: k=11; break; 
		case 0xbe: k=0; break; 
		case 0x7e: k=10; break; 
		case 0xed: k=12; break; 
		case 0xdd: k=9; break; 
		case 0xbd: k=8; break; 
		case 0x7d: k=7; break; 
		case 0xeb: k=14; break; 
		case 0xdb: k=6; break; 	
		case 0xbb: k=5;break; 
		case 0x7b: k=4;break; 
		case 0xe7: k=15;break; 
		case 0xd7: k=3;break; 
		case 0xb7: k=2;break; 
		case 0x77: k=1;break; 
		default  : k=16;break;
	}                                      
	}
}
  return k;
}

/********************* 键值判断程序**********************/
void keyscan(void)
{   uint key;
    uchar gw,sw;
	key=getch();
	delay(50);
    switch(key) //不同的键值做不同的处理
    {case 15:        count++;                          //mode 功能键
	                 if((count>=1)&&(count<=6))
	                 char_display(0x00,LabelCount++);
					 else
					 {count=0;
					  LabelCount=0x3e;
					  char_display(0x00,0x20);
					 }
					 break;  
     case 14:		 GetPCF8563(second,1,vbuf);    
                     if(vbuf[0]&0x80)
					 {lcd_init();
					  lcd_display(0x41,battery_low);
					  delay(1500);
					  lcd_init();
					  vbuf[0]=vbuf[0]&0x7f;
                      SetPCF8563(second,vbuf[0]);					  count=0;	     
					 }
				     else
					 {lcd_init();
					  lcd_display(0x01,battery_ok);
					  delay(1500);
					  lcd_init();
					 }
					 count=0;
					 EnterCount=0;
					 AlarmCount=0;
					 DataCount=0;
					 LightCount=0;
				     break;
	 case 12:		 if(count==1)                      //相加键,递增键为1是调节年寄存器中的数值!
					 {    
						  gw=rbuf[5]&0x0f;             //年的个位十位分离
                          sw=(rbuf[5]>>4)&0x0f;
						  if(gw==0x09)                 //判断个位和十位是否为9
						  {
						     if(sw==0x09)
							 {gw=0;
							  sw=0;
							 }
							 else
							 {  gw=0;
							    sw+=1;
							 }
						  }		  
					      else
						  gw+=1;
						  
						  rbuf[5]=(sw<<4)+gw;
						  SetPCF8563(year,rbuf[5]);
					}
					else if(count==2)      			  //调节月寄存器中的数值!
					{    
					     rbuf[4]=rbuf[4]&0x1f;
						 if(rbuf[4]==0x09)
						 rbuf[4]=0x10;
						 else if(rbuf[4]==0x12)
						 rbuf[4]=0x01;
						 else
						 rbuf[4]+=1;
						 SetPCF8563(month,rbuf[4]);
					}
					else if(count==4)
					{    
					     rbuf[3]=rbuf[3]&0x07;
						 if(rbuf[3]==0x06)
						 rbuf[3]=0x00;
						 else
						 rbuf[3]=rbuf[3]+1;
						 SetPCF8563(week,rbuf[3]);
					}
					else if(count==3)
					{   
    				     rbuf[2]=rbuf[2]&0x3f;
						 gw=rbuf[2]&0x0f;
                         sw=(rbuf[2]>>4)&0x0f;
					     if(rbuf[2]==0x31)                 //判断个位和十位是否为9
						  {gw=1;
						   sw=0;
						  }	  
					     else if(gw==0x09)
						  {gw=0;
						   sw+=1;
						  }	 
 						 else 
						   gw+=1;
						  rbuf[2]=(sw<<4)+gw;
						  SetPCF8563(day,rbuf[2]);
					}
					else if(count==5)
					{    
					     rbuf[1]=rbuf[1]&0x3f;
						 if(rbuf[1]==0x09)
						 rbuf[1]=0x10;
						 else if(rbuf[1]==0x19)
						 rbuf[1]=0x20;
						 else if(rbuf[1]==0x23)
						 rbuf[1]=0x0;
						 else 
						 rbuf[1]+=1;
						 SetPCF8563(hour,rbuf[1]);
					}
                    else if(count==6)
					{
						rbuf[0]=rbuf[0]&0x7f;
						gw=rbuf[0]&0x0f;
                        sw=(rbuf[0]>>4)&0x0f;
						if(gw==0x09)
						{ if(sw==0x05)
						  {sw=0;
						   gw=0;
						  }
						  else
						  {gw=0;
						   sw+=1;						  
						  }
                        }
						else
						gw+=1;
						rbuf[0]=(sw<<4)+gw;
						SetPCF8563(minute,rbuf[0]);                        
					}
					else 
					break;
					break;

    case 13:        if(count==1)                      //相减键,相减键为1是调节年寄存器中的数值!
					 {    
						  gw=rbuf[5]&0x0f;             //年的个位十位分离
                          sw=(rbuf[5]>>4)&0x0f;
						  if(gw==0x0)                 //判断个位和十位是否为0
						  {
						     if(sw==0x0)
							 {gw=9;
							  sw=9;
							 }
							 else
							 {  gw=9;
							    sw-=1;
							 }
						  }		  
					      else
						  gw-=1;
						  
						  rbuf[5]=(sw<<4)+gw;
						  SetPCF8563(year,rbuf[5]);
					}
					else if(count==2)      			  //调节月寄存器中的数值!
					{    
					     rbuf[4]=rbuf[4]&0x1f;
						 if(rbuf[4]==0x10)
						 rbuf[4]=0x9;
						 else if(rbuf[4]==0x01)
						 rbuf[4]=0x12;
						 else
						 rbuf[4]-=1;
						 SetPCF8563(month,rbuf[4]);
					}
					else if(count==4)
					{    
					     rbuf[3]=rbuf[3]&0x07;
						 if(rbuf[3]==0x0)
						 rbuf[3]=0x06;
						 else
						 rbuf[3]=rbuf[3]-1;
						 SetPCF8563(week,rbuf[3]);
					}
					else if(count==3)
					{   
    				     rbuf[2]=rbuf[2]&0x3f;
						 gw=rbuf[2]&0x0f;
                         sw=(rbuf[2]>>4)&0x0f;
					     if(rbuf[2]==0x01)                 //判断个位和十位是否为1
						  {gw=1;
						   sw=3;
						  }	  
					     else if(gw==0x0)
						  {gw=9;
						   sw-=1;
						  }	 
 						 else 
						   gw-=1;
						  rbuf[2]=(sw<<4)+gw;
						  SetPCF8563(day,rbuf[2]);
					}
					else if(count==5)
					{    
					     rbuf[1]=rbuf[1]&0x3f;
						 if(rbuf[1]==0x10)
						 rbuf[1]=0x9;
						 else if(rbuf[1]==0x20)
						 rbuf[1]=0x19;
						 else if(rbuf[1]==0x0)
						 rbuf[1]=0x23;
						 else 
						 rbuf[1]-=1;
						 SetPCF8563(hour,rbuf[1]);
					}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -