Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help to Solve Error in I2C RTC DS1307 C Code

Status
Not open for further replies.

jay_3189

Banned
Full Member level 1
Joined
Sep 19, 2013
Messages
104
Helped
0
Reputation
0
Reaction score
0
Trophy points
16
Location
Ahmedabad
Activity points
0
Help to print time in Hyper terminal from I2C RTC DS1307 C Code

I am just doing RTC I2C Interfacing with below code in Keil IDE with at89c51 controller and want to display time in hyper terminal through rs232 but there i dont know that how to write print function to GetTime and GetDate.

Please help me to solve this and also need suggestion that in my project i want to automate 6 valves continuosly by taking this time as reference time (at a time more than one valve could also be in ON Condition.)
HTML:
[CODE]
#include <stdio.h> 
#include<reg51.h>
void serial_init(void);
void DS1307_Init();
void DS1307_SetTime(unsigned char hh, unsigned char mm, unsigned char ss);
void DS1307_SetDate(unsigned char dd, unsigned char mm, unsigned char yy);
void DS1307_GetTime(unsigned char *h_ptr,unsigned char *m_ptr,unsigned char *s_ptr);
void DS1307_GetDate(unsigned char *d_ptr,unsigned char *m_ptr,unsigned char *y_ptr);
void DS1307_Write(unsigned char dat);
unsigned char DS1307_Read();
void I2C_Clock(void);
void I2C_Start();
void I2C_Stop(void);
void I2C_Write(unsigned char dat);
unsigned char I2C_Read(void);
void I2C_Ack();
void I2C_NoAck();
void delay_us(unsigned int us_count);
void delay_ms(unsigned int ms_count);
void delay_sec(unsigned char sec_count);

sbit SCL=P0^6; //SCL Connected to P0.6 
sbit SDA=P0^7; //SDA Connected to P0.7

#define DS1307_ID 0xD0		// DS1307 ID
#define SEC_ADDRESS	0x00	// Address to access Ds1307 SEC register
#define DATE_ADDRESS 0x04	// Address to access Ds1307 DATE register
#define CONTROL 0x07		// Address to access Ds1307 CONTROL register

void main(void)
{
		DS1307_Init();
	    DS1307_SetTime(10, 55, 15);
		DS1307_SetDate(12, 11, 13);
		serial_init();
		while(1)
	   	{
				DS1307_GetTime(0x02, 0x01, 0x00);
				printf("Time is in hh:mm:ss =  %d:%d:%d\n", 0x02, 0x01, 0x00);
			   	DS1307_GetDate(0x04, 0x05, 0x06);
			   	printf("The Time is in dd/mm/yy =  %d/%d/%d\n", 0x04, 0x05, 0x06);
	   	}
}

/*-------------------------------------------------------------
					DS1307 RTC
--------------------------------------------------------------*/
/*This function is used to initialize the Ds1307 RTC.
Ds1307 ic is enabled by sending the DS1307 id on the I2C bus. 
After selecting DS1307, write 0x00 into Control register of Ds1307*/
void DS1307_Init()
{
	I2C_Start();	// Start I2C communication
	DS1307_Write(DS1307_ID); // Connect to DS1307 by sending its ID on I2c Bus 
	DS1307_Write(CONTROL); // Select the Ds1307 ControlRegister to configure Ds1307
	DS1307_Write(0x00);	// Write 0x00 to Control register to disable SQW-Out
	I2C_Stop();	// Stop I2C communication after initilizing DS1307
}

/*This function is used to set Time(hh,mm,ss) into the Ds1307 RTC.
Ds1307 ic is enabled by sending the DS1307 id on the I2C bus.	  
After selecting DS1307, select the RAM address 0x00 to point to sec Initilze Sec, MIN, Hour one after the other.
Stop the I2c communication.*/
void DS1307_SetTime(unsigned char hh, unsigned char mm, unsigned char ss)
{
	I2C_Start();	// Start I2C communication
	DS1307_Write(DS1307_ID); // connect to DS1307 by sending its ID on I2c Bus 
	DS1307_Write(SEC_ADDRESS); // Select the SEC RAM address
	DS1307_Write(ss);	// Write sec on RAM address	00H
	DS1307_Write(mm);	// Write min on RAM address	01H
	DS1307_Write(hh);	// Write hour on RAM address 02H
	I2C_Stop();	// Stop I2C communication after Setting the Time
}

/*This function is used to set Date(dd,mm,yy) into the Ds1307 RTC.
Ds1307 ic is enabled by sending the DS1307 id on the I2C bus. 
After selecting DS1307, select the RAM address 0x04 to point to day Initilze Day,Month and Year one after the other.
Stop the I2c communication.*/ 
void DS1307_SetDate(unsigned char dd, unsigned char mm, unsigned char yy)
{
	I2C_Start();	// Start I2C communication
	DS1307_Write(DS1307_ID); // connect to DS1307 by sending its ID on I2c Bus 
	DS1307_Write(DATE_ADDRESS); // Request DAY RAM address at 04H
	DS1307_Write(dd);	// Write date on RAM address	04H
	DS1307_Write(mm);	// Write month on RAM address 05H
	DS1307_Write(yy);	// Write year on RAM address	06h
	I2C_Stop();	// Stop I2C communication after Setting the Date
}

/*This function is used to get the Time(hh,mm,ss) from Ds1307 RTC. 
Ds1307 ic is enabled by sending the DS1307 id on the I2C bus. 
After selecting DS1307, select the RAM address 0x00 to point to sec Get Sec, MIN, Hour one after the other.
Stop the I2c communication.*/
void DS1307_GetTime(unsigned char *h_ptr,unsigned char *m_ptr,unsigned char *s_ptr)
{
	I2C_Start();	// Start I2C communication			
	DS1307_Write(DS1307_ID);	// connect to DS1307 by sending its ID on I2c Bus
	DS1307_Write(SEC_ADDRESS);	// Request Sec RAM address at 00H	
	I2C_Stop();	// Stop I2C communication after selecting Sec Register

	I2C_Start();	// Start I2C communication
	DS1307_Write(0xD1);	// connect to DS1307( under Read mode) by sending its ID on I2c Bus	 
	  
*s_ptr = DS1307_Read();  I2C_Ack();	// read second and return Positive ACK 
*m_ptr = DS1307_Read();  I2C_Ack();	// read minute and return Positive ACK
*h_ptr = DS1307_Read();  I2C_NoAck();   // read hour and return Negative/No ACK

I2C_Stop();	// Stop I2C communication after reading the Time   
}

/*This function is used to get the Date(y,m,d) from Ds1307 RTC.
Ds1307 ic is enabled by sending the DS1307 id on the I2C bus.
After selecting DS1307, select the RAM address 0x00 to point to DAY Get Day, Month, Year one after the other.
Stop the I2c communication*/
void DS1307_GetDate(unsigned char *d_ptr,unsigned char *m_ptr,unsigned char *y_ptr)
{
	I2C_Start();	// Start I2C communication
	DS1307_Write(DS1307_ID); // connect to DS1307 by sending its ID on I2c Bus 
	DS1307_Write(DATE_ADDRESS); // Request DAY RAM address at 04H
	I2C_Stop();	// Stop I2C communication after selecting DAY Register

	I2C_Start();	// Start I2C communication
	DS1307_Write(0xD1);	// connect to DS1307( under Read mode) by sending its ID on I2c Bus

*d_ptr = DS1307_Read(); I2C_Ack();	// read Day and return Positive ACK
*m_ptr = DS1307_Read(); I2C_Ack();	// read Month and return Positive ACK
*y_ptr = DS1307_Read(); I2C_NoAck();   // read Year and return Negative/No ACK

I2C_Stop();	// Stop I2C communication after reading the Time  
}

/*This function is used to write a byte of data into Ds1307 RTC. 
This function calls I2C_write function to perform the same*/
void DS1307_Write(unsigned char dat)
{
	I2C_Write(dat); // Connect to DS1307 by sending its ID on I2c Bus 
	I2C_Clock();
}

/*This function is used to read a byte of data from Ds1307 RTC.
This function calls I2C_Read function to perform the same*/
unsigned char DS1307_Read()
{
	unsigned char dat;
	dat = I2C_Read(); // Connect to DS1307 by sending its ID on I2c Bus 
	return(dat);
}



/*-------------------------------------------------------------
					I2C
--------------------------------------------------------------*/
/*This function is used to generate a clock pulse on SCL line.*/
void I2C_Clock(void)
{
	delay_us(1); 
	SCL = 1;	// Wait for Some time and Pull the SCL line High
	delay_us(1);	// Wait for Some time
	SCL = 0;	// Pull back the SCL line low to Generate a clock pulse
}

/*This function is used to generate I2C Start Condition. 
Start Condition: SDA goes low when SCL is High.*/  
void I2C_Start()
{
	SCL = 0;	// Pull SCL low
	SDA = 1;	// Pull SDA High
	delay_us(1);
	SCL = 1;	//Pull SCL high
	delay_us(1);
	SDA = 0;	//Now Pull SDA LOW, to generate the Start Condition
	delay_us(1);
	SCL = 0;	//Finally Clear the SCL to complete the cycle
}

/*This function is used to generate I2C Stop Condition. 
Stop Condition: SDA goes High when SCL is High.*/
void I2C_Stop(void)
{
	SCL = 0;	// Pull SCL low	
	delay_us(1);		
	SDA = 0;	// Pull SDA  low	
	delay_us(1);		
	SCL = 1;	// Pull SCL High	
	delay_us(1);		
	SDA = 1;	// Now Pull SDA High, to generate the Stop Condition
}		

/*This function is used to send a byte on SDA line using I2C protocol 
8bit data is sent bit-by-bit on each clock cycle. MSB(bit) is sent first and LSB(bit) is sent at last.
Data is sent when SCL is low.*/		
void I2C_Write(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)	// loop 8 times to send 1-byte of data
	{
	 	SDA = dat & 0x80;	// Send Bit by Bit on SDA line
		I2C_Clock();	// Generate Clock at SCL
		dat = dat<<1;
	}
	SDA = 1;	// Set SDA at last
}


/*This fun is used to receive a byte on SDA line using I2C protocol.
8bit data is received bit-by-bit each clock and finally packed into Byte.
MSB(bit) is received first and LSB(bit) is received at last.*/

unsigned char I2C_Read(void)
{
	unsigned char i, dat=0x00;
	SDA=1;	//Make SDA as I/P
	for(i=0;i<8;i++)	// loop 8times to read 1-byte of data
	{
		delay_us(1);
		SCL = 1;	// Pull SCL High
		delay_us(1);
		dat = dat<<1;	//dat is Shifted each time and
		dat = dat | SDA;	//ORed with the received bit to pack into byte
		SCL = 0;	// Clear SCL to complete the Clock
	}
	return dat;	// Finally return the received Byte*
}

/*This function is used to generate a the Positive ACK 
pulse on SDA after receiving a byte.*/
void I2C_Ack()
{
	SDA = 0; //Pull SDA low to indicate Positive ACK 
	I2C_Clock(); //Generate the Clock
	SDA = 1;	// Pull SDA back to High(IDLE state)
}

/*This function is used to generate a the Negative/NO ACK 
pulse on SDA after receiving all bytes.*/
void I2C_NoAck()
{
	SDA = 1;	//Pull SDA high to indicate Negative/NO ACK
	I2C_Clock();	// Generate the Clock
	SCL = 1;	// Set SCL */
}


/*-------------------------------------------------------------
					Delay
--------------------------------------------------------------*/
/*It genarates a approximate delay of 10us for each count,
if 5000 is passed as the argument then it generates a delay of apprx 50ms.*/
void delay_us(unsigned int us_count)
{
	while(us_count!=0)
	{
		us_count--;
	}
}

/*It genarates a approximate delay of 1ms for each count, 
if 1000 is passed as the argument then it generates delay of apprx 1000ms(1sec)*/
void delay_ms(unsigned int ms_count)
{
	while(ms_count!=0)
	{
		delay_us(112);   //delay_us is called to generate 1ms delay
		ms_count--;
	}	
}

/*It genarates a approximate delay of 1sec for each count,
if 10 is passed as the argument then it generates delay of apprx 10sec
note: A max of 255 sec delay can be generated using this function.*/
void delay_sec(unsigned char sec_count)
{
	while(sec_count!=0)
	{
		delay_ms(1000); //delay_ms is called to generate 1sec delay 
		sec_count--;
	}
}

//-------------------------------------------------
//Setup the serial port for 9600 baud at 11.0592MHz.
//-------------------------------------------------
void serial_init(void)
{
    SCON  = 0x50;                  /* SCON: mode 1, 8-bit UART, enable rcvr         */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload                    */
    TH1   = 0xFD;               /* TH1:  reload value for 9600 baud @ 11.0592MHz*/
    TR1   = 1;                  /* TR1:  timer 1 run                               */
    TI    = 1;                  /* TI:   set TI to send first char of UART           */
}[/CODE]
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top