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

📄 ds1302.c

📁 这个是uclinux里面涉及到的时钟的函数
💻 C
字号:
/*********************************************************************	DS1302.C		Pat Adamo, ADEMCO	05/26/99	This file handles the Dallas DS1302 Real Time Clock.	On the Motorola Coldfire MCF5206, the DS1302 requires three port	pins, designated as follows...		RESET*  Port PP0		CLOCK   Port PP1		DATA    Port PP2**********************************************************************/#include "ds1302.h"//MBAR must have been set to this by someone else//This must match the setting done by the hardware set-up#define MCF_MBAR	0x10000000//Additional Sim registers#define MCFPP_PPDDR	0x1c5	//Port A Data Direction Register (byte, r/w)#define MCFPP_PPDAT	0x1c9	//Port A Data Register (byte, r/w)#define MCFSIM_PAR	0xcb	//Pin Assignment reg (r/w)//write//#define DS1302(ds1302_bit,logical_value) \//	{ \//	if (!logical_value)         \//		*((volatile unsigned char *)(MCF_MBAR + MCFPP_DAT)) = \//		*((volatile unsigned char *)(MCF_MBAR + MCFPP_DAT)) &//(0xff-ds1302_bit); \ 	  else \//		*((volatile unsigned char *)(MCF_MBAR + MCFPP_DAT)) = \//		*((volatile unsigned char *)(MCF_MBAR + MCFPP_DAT)) |//ds1302_bit; \ 	}#define DS1302IN(ds1302_bit) (*((volatile unsigned char *)(MCF_MBAR + MCFPP_PPDAT)) & ds1302_bit)//local storageTIME_STRUCT ds_1302_time;						/* copy of system time *///writevoid DS1302(unsigned char ds1302_bit,unsigned int logical_value)	{ 	if (!logical_value)		*((volatile unsigned char *)(MCF_MBAR + MCFPP_PPDAT)) =			*((volatile unsigned char *)(MCF_MBAR +MCFPP_PPDAT))& (0xff-ds1302_bit);		else		*((volatile unsigned char *)(MCF_MBAR + MCFPP_PPDAT)) =		*((volatile unsigned char *)(MCF_MBAR +MCFPP_PPDAT))|ds1302_bit;	}/*******************************************************************	Setup_1302_Port		Initialize Port Pins to access DS1302 Clock.	Note that all three pins are defined initialliy as outputs.	When you want to read a port pin, you have to turn it	around.	MCF5206...	PP0 = CLOCK	PP1 = RST*	PP2 = DATA********************************************************************/void Setup_1302_Port(void)   {	unsigned char c;	//get the current value of the Pin Assignment Register	c = *(volatile unsigned char *)(MCF_MBAR + MCFSIM_PAR);	c = c & 0xef;	//PAR4 = 0, selects PP0-4 on port instead of 						//BDM PST0-3	*(volatile unsigned char *)(MCF_MBAR + MCFSIM_PAR) = c;	//and make sure that we have the appropriate direction for	//the port pins	c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);	c = c | (CLK_1302 + RST_1302 + DAT_1302);	//selects all output	*(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;		Idle_1302();			/* set the port pins idle */	return;	} //end proc Setup_1302_Port()/*******************************************************************	Read_1302_Port		MCF5206...	PP0 = RESET*	PP1 = CLOCK	PP2 = DATA********************************************************************/unsigned char Read_1302_Port(void)   {	unsigned char c;	c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDAT);	c = c & (CLK_1302 + RST_1302 + DAT_1302);//three DS1302 lines only//	c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);	return(c);	} //end proc Read_1302_Port()/*******************************************************************	Read_1302_Data	Reads all 8 bytes of data from the DS1302.	Inputs: 	TimeBuffer- Pointer to 8 byte unsigned char array where data				will be placed once read from the clock	Returns in TimeBuffer:	TimeBuffer[0]	seconds: msb=1, clock hold, BCD seconds	TimeBuffer[1]	minutes: 0,BCD minutes	TimeBuffer[2]	hours:   msb=1,12 hour/0,24 hour, BCD hour				msb=0,	0-23 BCD				msb=1,  {10}{0=am/1=pm}01-12 BCD	TimeBuffer[3]	day of month: BCD day 0-31	TimeBuffer[4]	month:	BCD 1-12	TimeBuffer[5]	day of week: BCD 1-7 1=Sunday	TimeBuffer[6]	year: BCD 00-99	TimeBuffer[7]	write protect: msb=1, write protect						 msb=0, write en	returns: 0 if all is well, non-zero if clock was stopped	NOTE: If clock was stopped, returns non-zero and time is			indicated as Jan 1, 1999, 12:00:00 Noon********************************************************************/unsigned int Read_1302_Data(unsigned char * TimeBuffer)	{	unsigned char Cmd_Byte;				/*clock command*/	unsigned char databyte;         	/*temp data byte*/  	unsigned char shifter;				/* bit selector */	unsigned int i,j;	unsigned char c;	DS1302(CLK_1302,LOW);	DS1302(DAT_1302,LOW);	DS1302(RST_1302,HIGH);		Cmd_Byte = READ_CMD; /* set command to the 1302 for burst read operation */	shifter = 0x01;    for(i=0; i<8; i++)		/* shift the read command */   	{		if (shifter & Cmd_Byte)			DS1302(DAT_1302,HIGH);		  else	 		DS1302(DAT_1302,LOW); /* set up the data line */ 		DS1302(CLK_1302,HIGH);      shifter = shifter << 1;      DS1302(CLK_1302,LOW);	/* toggle the clock */   	} //next i//	//PB5 (DATA Line) is input//   write_word_port((unsigned long)(PIO_PBDDR+OCP_BASE),//	read_word_port((unsigned long)(PIO_PBDDR+OCP_BASE)) & (65535-DAT_1302));	//and make sure that we have the appropriate direction for	//the data port pin - to INPUT	c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);	c = c & (0xff - DAT_1302);	//selects data line as input	*(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;   for(i=0; i<8; i++)		/* read in the next 7 bytes returned */   	{      databyte = 0;             /* start clean */      for(j=0; j<8; j++)	/* read in a byte */      	{      	//make room for the new bit      	databyte = databyte >> 1; /* shift the collected data right */      	if (DS1302IN(DAT_1302))	 			databyte |= 0x80;			  else	 			databyte &= 0x7f;    /* capture the state of the data line */      	DS1302(CLK_1302,HIGH);      	DS1302(CLK_1302,LOW);	/* clock the chip */      	} //next j      TimeBuffer[i] = databyte;	/* save it in the buffer */   	} //next i//   //PB5 (DATA Line) is output//   write_word_port((unsigned long)(PIO_PBDDR+OCP_BASE),//	read_word_port((unsigned long)(PIO_PBDDR+OCP_BASE)) | DAT_1203);	//and make sure that we have the appropriate direction for	//the data port pin - back to OUTPUT	c = *(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR);	c = c  | DAT_1302;	//selects data line as output	*(volatile unsigned char *)(MCF_MBAR + MCFPP_PPDDR) = c;	Idle_1302();			/* set the port pins idle */	//clean-up of time if time is bad (like when clock is stopped...)	if (TimeBuffer[0] > 0x59)		{		//The time is bogus, make an assumption		TimeBuffer[5] = 4;		//day of week: BCD 1-7 1=Sunday		TimeBuffer[6] = 0x99;	//year: BCD 00-99		TimeBuffer[4] = 0x1;		//month:	BCD 1-12		TimeBuffer[3] = 0x1;		//day of month: BCD day 0-31		TimeBuffer[1] = 0x00;	//minutes: 0,BCD minutes		TimeBuffer[2] = 0x12;	//hours:   msb=1,12 hour/0,24 hour, BCD hour										//msb=0,	0-23 BCD										//msb=1,  {10}{0=am/1=pm}01-12 BCD		TimeBuffer[0] = 0;		//0 sec										//seconds: msb=1, clock hold, BCD seconds		return(1);	//indicate that clock was stopped		} //end if (TimeBuffer[0] > 59)	return(0);	//indicate that clock is running	} /* end Read_1302_Data() *//********************************************************************	WRITE_1302_Data	This routine will write all 8 bytes to the 1302 clock chip.	Inputs: 	TimeBuffer- Pointer to 8 byte unsigned char array where data				will be placed once read from the clock	Obtains from TimeBuffer:	TimeBuffer[0]	seconds: msb=1, clock hold, BCD seconds	TimeBuffer[1]	minutes: 0,BCD minutes	TimeBuffer[2]	hours:   msb=1,12 hour/0,24 hour, BCD hour				msb=0,	0-23 BCD				msb=1,  {10}{0=am/1=pm}01-12 BCD	TimeBuffer[3]	day of month: BCD day 0-31	TimeBuffer[4]	month:	BCD 1-12	TimeBuffer[5]	day of week: BCD 1-7 1=Sunday	TimeBuffer[6]	year: BCD 00-99	TimeBuffer[7]	write protect: msb=1, write protect				       msb=0, write en	Returns: None*********************************************************************/void Write_1302_Data(unsigned char * TimeBuffer)	{	unsigned char Cmd_Byte;				/*clock command*/	unsigned char databyte;         	/*temp data byte*/  	unsigned char shifter;				/* bit selector */  	unsigned int i,j;   DS1302(CLK_1302,LOW);   DS1302(DAT_1302,LOW);   DS1302(RST_1302,HIGH);   Cmd_Byte = WRITE_CMD;	/* set command to the 1302 for   								burst write operation */   shifter = 0x01;   for(i=0; i<8; i++)		/* shift out the command */   	{      if (shifter & Cmd_Byte)	 		DS1302(DAT_1302,HIGH);		  else	 		DS1302(DAT_1302,LOW);	/* set up the data port pin */      DS1302(CLK_1302,HIGH);      shifter = shifter << 1;      DS1302(CLK_1302,LOW);		/* clock the chip */   	} //next i   for(i=0; i<8; i++)		/* output all 8 bytes to DS1302 */   	{      shifter = 0x01;      databyte = TimeBuffer[i];  /* get byte from buffer */      for(j=0; j<8; j++)	/* shift out data */      	{      	if (shifter & databyte)	 			DS1302(DAT_1302,HIGH);			  else	 			DS1302(DAT_1302,LOW);	/* set up the data port pin */	      DS1302(CLK_1302,HIGH);      	shifter = shifter << 1;      	DS1302(CLK_1302,LOW);		/* clock the chip */      	} //next j   	} //next i   Idle_1302();			/* set the port pins idle */	return;	} /* end Write_1302_Data() *//*******************************************************************	Enable_1302	Write enables the Dallas Semi 1302 clock chip.********************************************************************/void Enable_1302(void)	{	unsigned char Cmd_Byte;				/*clock command*/	unsigned char databyte;         	/*temp data byte*/	unsigned char shifter;				/* bit selector */	unsigned int i,j;		DS1302(CLK_1302,LOW);   DS1302(DAT_1302,LOW);   DS1302(RST_1302,HIGH);   Cmd_Byte = 0x8e;		/* set command to the 1302 for   							write to write prot register */   shifter = 0x01;   for(i=0; i<8; i++)	/* shift out the command */   	{      if (shifter & Cmd_Byte)	 		DS1302(DAT_1302,HIGH);		  else	 		DS1302(DAT_1302,LOW);      DS1302(CLK_1302,HIGH);      shifter = shifter << 1;		DS1302(CLK_1302,LOW);   	} //next i   shifter = 0x01;   databyte =0;			/* we want to write enable the								DS1302 chip */   for(j=0; j<8; j++)	/* shift out the data */   	{      if (shifter & databyte)	 		DS1302(DAT_1302,HIGH);		  else	 		DS1302(DAT_1302,LOW);      DS1302(CLK_1302,HIGH);      shifter = shifter << 1;      DS1302(CLK_1302,LOW);		/* clock the chip */   	} //next j   Idle_1302();			/* idle the port pins */	return;	} /* end Enable_1302() *//*******************************************************************	Idle_1302	This routine will set the port pins that drive the clock to	their idle states.********************************************************************/void Idle_1302(void)	{   DS1302(RST_1302,LOW);   DS1302(DAT_1302,HIGH);   DS1302(CLK_1302,HIGH);	return;	} /* end Idle_1302() *//*******************************************************************	Lock_1302	This routine will LOCK the clock and stop its oscillator to	preserve Battery Life.	Uses TimeBuffer[] as temporary storage.********************************************************************/void Lock_1302 (void)   {	unsigned char TimeBuffer[8];				//temp storage   Read_1302_Data(&TimeBuffer[0]);        //get the time	TimeBuffer[0] = TimeBuffer[0]|0x80;    //halt the clock   Enable_1302();    							//write enable the clock	Write_1302_Data(&TimeBuffer[0]);       //write back the halted time	return;   } /* end proc Lock_1203() *//*******************************************************************	Set_Time	This routine SETs the clock and start its oscillator, write-	protecting the clock registers.	Obtains time from TimeBuffer[].********************************************************************/void Set_Time(unsigned char * TimeBuffer)   {   TimeBuffer[7] = '\x80';         //write protect the chip after write   Enable_1302();                  //write enable the clock   Write_1302_Data(TimeBuffer);              //write the clock and start it up   } /* end proc Set_Time() *//*******************************************************************	Get_Time	This routine GETs the time from the Dallas 1302 clock.	The time is returned in TimeBuffer.	This function returns 0 when the clock is operating properly.	If the clock was locked (stopped) the default time is returned	as 1/1/99, 12:00Noon and the function returns non-zero.********************************************************************/unsigned int Get_Time(unsigned char * TimeBuffer)   {	unsigned int clock_locked;		//get the time and put it in TimeBuffer[]	clock_locked = Read_1302_Data(TimeBuffer);		//store the time in system variable time....	//Note that since the values in the RTC and TimeBuffer are in	//BCD, we need to convert back to normal numbers!	ds_1302_time.year = (((TimeBuffer[6] & 0xf0)>>4)*10)+(TimeBuffer[6] & 0xf);	ds_1302_time.month = (((TimeBuffer[4] & 0xf0)>>4)*10)+(TimeBuffer[4] & 0xf);	ds_1302_time.date = (((TimeBuffer[3] & 0xf0)>>4)*10)+(TimeBuffer[3] & 0xf);	ds_1302_time.hour = (((TimeBuffer[2] & 0x30)>>4)*10)+(TimeBuffer[2] & 0xf);	ds_1302_time.min = (((TimeBuffer[1] & 0xf0)>>4)*10)+(TimeBuffer[1] & 0xf);	ds_1302_time.sec = (((TimeBuffer[0] & 0xf0)>>4)*10)+(TimeBuffer[0] & 0xf);	ds_1302_time.dayOfWeek = TimeBuffer[5];	return(clock_locked);	} /* end proc Get_Time() */

⌨️ 快捷键说明

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