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

📄 ds1302.h

📁 RTC芯片
💻 H
字号:
/*******************************************************************
*【文 件 名】:DS1302.h                                            *
*【建立日期】:2008年7月4日                                        *
*【修改日期】:2008年7月5日                                        *
*【文件作用】:DS1302驱动程序,提供直接调用函数                    *
*【说    明】:显示格式:                                          *
*                DATA:年-月-日-星期                             *
*                TIME:时:分:秒                                   *
*------------------------------------------------------------------*
*【作    者】:郭鑫(ben)                                           *
*【版    权】:国家创新性实验项目,编号GCS07001                    *
*******************************************************************/


#ifndef _DS1302_08_07_04_
#define _DS1302_08_07_04_

#include <reg52.h>


//------------定义------------
#define delay_value3 10

typedef struct 
{
	uchar Second;
	uchar Minute;
	uchar Hour;
	uchar Week;
	uchar Day;
	uchar Month;
	uchar Year;
	uchar DateString[11];
	uchar TimeString[9];
}time_struct;

time_struct sys_time;

#define DS1302_SECOND	0x80   //各个时间值的地址
#define DS1302_MINUTE	0x82
#define DS1302_HOUR		0x84 
#define DS1302_DAY		0x86
#define DS1302_MONTH	0x88
#define DS1302_WEEK		0x8A
#define DS1302_YEAR		0x8C

//-------------------------管脚定义--------------------------------	 
sbit  ds1302_clk = P3^4;   //实时时钟时钟线引脚
sbit  ds1302_io  = P3^3;   //实时时钟数据线引脚
sbit  ds1302_rst = P3^2;   //实时时钟复位线引脚
sbit  acc0= ACC^0;         //数据读入
sbit  acc7= ACC^7;         //数据读出



//初始时间			  秒   分	时	 日   月  星期	年   
uchar start_time[7]={0x10,0x47,0x14,0x22,0x03,0x06,0x08};
//uchar pdata shijian[]="时间:";
//uchar pdata riqi[]="日期:";				  

//----------函数声明-------------
void ds1302_byte_w(uchar byt);					  //DS1302写入一个字节
uchar ds1302_byte_r(void);						  //DS1302读出一个字节

void ds1302_w(uchar adds,uchar dat_writed);		  //DS1302数据写入某地址
uchar ds1302_r(uchar adds);						  //DS1302某地址数据读取

void ds1302_w_protect(bit flag);  
void ds1302_init_time(uchar *time_to_w);
void ds1302_initial(void);	                             //DS1302初始化

void ds1302_get_time(time_struct *cur_time);    //获取DS1302时间日期	
void ds1302_set_time(void);                      //键控设置时间日期

void call_ds1302(void); 							//供外部调用


//----------DS1302初始化----------
void ds1302_initial(void)
{
	uchar second;
	second=ds1302_r(DS1302_SECOND);
	ds1302_w_protect(0);
	if(second&0x80)		  
		ds1302_w(DS1302_SECOND,0x00);
//	ds1302_set_time(start_time);
	ds1302_w_protect(1);	
	lcd_cmd_w(0x01); //清屏
	lcd_setposition(1,2);
	lcd_str_w("日历系统");
	lcd_setposition(2,0);
	lcd_str_w("Data: ");

	lcd_setposition(3,0);
	lcd_str_w("Time: ");

	lcd_setposition(4,1);
	lcd_str_w("key4设置系统");

}//void ds1302_initial(void)


//-------DS1302读出一个字节----------
uchar ds1302_byte_r(void)
{
	uchar i;
  	for(i=8; i>0; i--)
  	{
		ACC=ACC>>1;
		acc7=ds1302_io;
		ds1302_clk=1;
		ds1302_clk=0;
//		delay(delay_value3);
	}
	return(ACC);
}//uchar ds1302_byte_w(void)

//---------DS1302写入一个字节--------------
void ds1302_byte_w(uchar byt)
{
	uchar i=0;
	ACC=byt;
	for(i=8;i>0;i--)
	{
		ds1302_io=acc0;
		ds1302_clk=1;
		ds1302_clk=0;
//		delay(delay_value3);
		ACC=ACC>>1;
	}
}//void ds1302_byte_r(uchar byt)

//-------------DS1302某地址数据读取--------------
uchar ds1302_r(uchar adds)
{
	uchar data_read;
  	ds1302_rst = 0;
 	ds1302_clk = 0;
 	ds1302_rst = 1;
 	ds1302_byte_w(adds|0x01); //            
 	data_read = ds1302_byte_r();      
 	ds1302_clk = 1;
 	ds1302_rst = 0;
 	return(data_read);	
}//uchar ds1302_r(uchar adds)


//-------------DS1302数据写入某地址------------
void ds1302_w(uchar adds,uchar data_writed)
{
  	ds1302_rst = 0;
 	ds1302_clk = 0;
 	ds1302_rst = 1;
 	ds1302_byte_w(adds);          
 	ds1302_byte_w(data_writed);         
 	ds1302_clk = 1;
 	ds1302_rst = 0;	
}//void ds1302_w(uchar dat,uchar adds)


//-----------DS1302是否写保护----------------
void ds1302_w_protect(bit flag)  				 //flag=0不保护,flag=1写保护
{
	if(flag)
		ds1302_w(0x8e,0x80);	
	else
		ds1302_w(0x8e,0x00);
}//void ds1302_w_protect(bit flag)




void ds1302_init_time(uchar *time_to_w)
{
	uchar i=0;
  	uchar adds = 0x80;
  	ds1302_w_protect(0);           //控制命令,WP=0,写操作
	for(i = 0; i < 7; i++)
  	{	
		ds1302_w(adds,time_to_w[i]);  // 秒 分 时 日 月 星期 年 
    	adds+=2;
  	}
  	ds1302_w_protect(1);          //控制命令,WP=1,写保护


}//void ds1302_set_time(uchar *time_to_w)



/*******************************************************************
*【函 数 名】:ds1302_get_time                                     *
*【修改日期】:2008年7月4日                                        *
*【文件作用】:获取DS1302时间值并转化位数组形式,供显示使用        *
*------------------------------------------------------------------*
*【备    注】:                                                    *
*******************************************************************/
void ds1302_get_time(time_struct *cur_time)		
{
	uchar temp_time;               //存放读取的临时时间
	temp_time = ds1302_r(DS1302_SECOND);
	cur_time->Second = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
	temp_time = ds1302_r(DS1302_MINUTE);
	cur_time->Minute = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
	temp_time = ds1302_r(DS1302_HOUR);
	cur_time->Hour = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
	temp_time = ds1302_r(DS1302_DAY);
	cur_time->Day = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);	
	
	temp_time = ds1302_r(DS1302_WEEK);
	cur_time->Week = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
	temp_time = ds1302_r(DS1302_MONTH);
	cur_time->Month = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
	temp_time = ds1302_r(DS1302_YEAR);
	cur_time->Year = ((temp_time&0x70)>>4)*10 + (temp_time&0x0F);
	
		cur_time->DateString[0] = cur_time->Year/10 + '0'; //年份
		cur_time->DateString[1] = cur_time->Year%10 + '0';
		cur_time->DateString[2] = '_';
		cur_time->DateString[3] = cur_time->Month/10 + '0'; //月份
		cur_time->DateString[4] = cur_time->Month%10 + '0';
		cur_time->DateString[5] = '_';
		cur_time->DateString[6] = cur_time->Day/10 + '0';
		cur_time->DateString[7] = cur_time->Day%10 + '0';
		cur_time->DateString[8] = '_';
		cur_time->DateString[9]	= cur_time->Week%10+'0';
		cur_time->DateString[10] = '\0';		

		cur_time->TimeString[0] = cur_time->Hour/10 + '0'; //时的十位
		cur_time->TimeString[1] = cur_time->Hour%10 + '0'; //时的各位
		cur_time->TimeString[2] = ':';
		cur_time->TimeString[3] = cur_time->Minute/10 + '0';
		cur_time->TimeString[4] = cur_time->Minute%10 + '0';
		cur_time->TimeString[5] = ':';
		cur_time->TimeString[6] = cur_time->Second/10 + '0';
		cur_time->TimeString[7] = cur_time->Second%10 + '0';
		cur_time->TimeString[8] = '\0';	
}//void ds1302_get_time(time_struct *cur_time)


/*******************************************************************
*【函 数 名】:ds1302_set_time                                     *
*【修改日期】:2008年7月5日                                        *
*【文件作用】:键控设置时间                                        *
*------------------------------------------------------------------*
*【备    注】:可能由于按键原因,设置反应慢,有待改进              *
*******************************************************************/
void ds1302_set_time(void)
{
// time_struct idata  CTE;
 time_struct idata  time;
// time_struct idata old_time;
 uint  idata clk_time;
 uchar idata time_flag[5];
 uint idata timeflag = 1;
// uint idata i=0;
 uchar max;

 if(key_check(4) == 1)    //调整时间
 {
//  lcd_cmd_w(0x01);
//  lcd_setposition(1,2);
//  lcd_str_w("日历系统");
//  lcd_setposition(2,0);
//  lcd_str_w("Date: ");
//  lcd_setposition(3,0);
//  lcd_str_w("Time: ");
  lcd_setposition(4,0);
  lcd_str_w("调整时间模式    ");

  while(1)
  {
//   ds1302_get_time(&CTE);
   ds1302_get_time(&time);

   lcd_setposition(2,3);
   lcd_str_w(time.DateString);
   lcd_setposition(3,3);
   lcd_str_w(time.TimeString);
   lcd_setposition(4,0);
   

   if(timeflag == 1)	//调整:年
   { 
    max = 99;
	clk_time = time.Year;
    lcd_str_w("现在调整: 年");
    lcd_setposition(2,3);
    lcd_str_w("  ");
    delay(50);
    lcd_setposition(2,3);
    time_flag[0] = clk_time/10 + '0';
    time_flag[1] = clk_time%10 + '0';
    time_flag[2] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   else if(timeflag == 2)//	调整: 月
   {
    max = 13;
	clk_time = time.Month;
    lcd_str_w("现在调整: 月");
    lcd_setposition(2,4);
    lcd_str_w("_  ");
    delay(50);
    lcd_setposition(2,4);
    time_flag[0] = '_';
    time_flag[1] = clk_time/10 + '0';
    time_flag[2] = clk_time%10 + '0';
    time_flag[3] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   else if(timeflag == 3)	   //调整: 日
   {
    max = 32;
    clk_time = time.Day;
    lcd_str_w("现在调整: 日");
    lcd_setposition(2,6);
    lcd_str_w("  ");
    delay(50);
    lcd_setposition(2,6);
    time_flag[0] = clk_time/10 + '0';
    time_flag[1] = clk_time%10 + '0';
    time_flag[2] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }
    
	else if(timeflag == 7)		 // 调整: 周
   {
    max = 8;
	clk_time = time.Week;
    lcd_str_w("现在调整: 周");
    lcd_setposition(2,7);
    lcd_str_w("_ ");
    delay(50);
    lcd_setposition(2,7);
    time_flag[0] ='_';
    time_flag[1] = clk_time%10 + '0';
    time_flag[2] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   else if(timeflag == 4)		 //调整: 时
   {
	max = 24;
    clk_time = time.Hour;
    lcd_str_w("现在调整: 时");
    lcd_setposition(3,3);
    lcd_str_w("  ");
    delay(50);
    lcd_setposition(3,3);
    time_flag[0] = clk_time/10 + '0';
    time_flag[1] = clk_time%10 + '0';
    time_flag[2] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   else if(timeflag == 5)  //调整: 分
   {
    max = 60;
    clk_time = time.Minute;
    lcd_str_w("现在调整: 分");
    lcd_setposition(3,4);
    lcd_str_w(":  ");
    delay(50);
    lcd_setposition(3,4);
    time_flag[0] = ':';
    time_flag[1] = clk_time/10 + '0';
    time_flag[2] = clk_time%10 + '0';
    time_flag[3] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   else if(timeflag == 6)   //调整: 秒
   {
    max = 60;
	clk_time = time.Second;
    lcd_str_w("现在调整: 秒");
    lcd_setposition(3,6);
    lcd_str_w("  ");
    delay(50);
    lcd_setposition(3,6);
    time_flag[0] = clk_time/10 + '0';
    time_flag[1] = clk_time%10 + '0';
    time_flag[2] = '\0';
    lcd_str_w(time_flag);
    delay(50);
   }

   lcd_setposition(4,6);				   //可以去掉
   time_flag[0]='(';
   time_flag[1]= clk_time/10 + '0';
   time_flag[2]= clk_time%10 + '0';
   time_flag[3]=')';
   time_flag[4]='\0';
   lcd_str_w(time_flag);


   if(key_check(4) == 1)	  //切换设置值
   {
      timeflag = timeflag + 1;
      if(timeflag == 8)
           timeflag = 1;
	goto again;
   }

   if(key_check(3) == 1)	  //值加1
   {

    clk_time = clk_time + 1;
	if(clk_time == max)
		if(timeflag == 2||timeflag == 7||timeflag == 3)
			clk_time = 1;
		else
			clk_time = 0;
			    
       clk_time = (((clk_time/10)<<4) &0xf0) + (((clk_time%10)&0x0f));
	   
	   ds1302_w_protect(0);          //控制命令,WP=1,写保护

       if(timeflag == 1)
  		    ds1302_w(0x8c,clk_time);	   
	   else if(timeflag == 7)
            ds1302_w(0x8a,clk_time);
	   else if(2 <= timeflag <= 6)
            ds1302_w((0x88-(timeflag-2)*2),clk_time);
		ds1302_w_protect(1);          //控制命令,WP=1,写保护
	 goto again;
	}

   if(key_check(2) == 1)	   //
   {

    if(clk_time != 0)
      clk_time = clk_time - 1; 
    clk_time = (((clk_time/10)<<4) &0xf0) + (((clk_time%10)&0x0f));
      	ds1302_w_protect(0);          //控制命令,WP=1,写保护

	if(timeflag == 1)
        ds1302_w(0x8c,clk_time);
	
	else if(timeflag == 7)
	     ds1302_w(0x8a,clk_time);
    
	else if(2<=timeflag <= 6)
        ds1302_w((0x88-(timeflag-2)*2),clk_time);
	ds1302_w_protect(1);          //控制命令,WP=1,写保护
	 goto again;
   }

again:

   if(key_check(1) == 1 || key_check(0) == 1)
   {
		ds1302_initial();
		return;
    
   }


  }
 }
}
	 


/*******************************************************************
*【函 数 名】:call_ds1302                                         *
*【修改日期】:2008年7月4日                                        *
*【文件作用】:供外部调用,调用即可启动DS1302                      *
*------------------------------------------------------------------*
*【备    注】:缺少ds1302_initial和while(1)                        *
*******************************************************************/
void call_ds1302()
{

		ds1302_get_time(&sys_time);
		lcd_setposition(2,3);
		lcd_str_w(sys_time.DateString);
		lcd_setposition(3,3);
		lcd_str_w(sys_time.TimeString);
		ds1302_set_time();						
}



#endif

⌨️ 快捷键说明

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