Where to save DS1307 program to get real time value

cpicrtc

I am integrating DS1307 in my project and using PIC32MX795F512L MCU. I have somehow managed to do I2C communication in it and getting the real time values. I am displaying the real time value in terminal using UART. So the time is updating automatically. But when I turned off the power to the device and turn it ON again, the DS1307 doesnt gave me the real time value instead it starts the time which I set in the code.

In the code I set, 14:27:12, so after turning it off and on again, the time started from 14:27:12 which I think should not happen. I have battery attached with DS1307.

So I thought to get a real time value, I might have to save the code somewhere else in the Micro Controller.

Need help regarding this.!

CODE:

int main(void)
{
  OpenUART1( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT  , UART_RX_ENABLE | UART_TX_ENABLE, (FPB/16/BAUDRATE)-1 );


  I2C2BRG = 0xA3;     //I2C Baudrate
  I2CEnable(EEPROM_I2C_BUS, TRUE);    //I2C module On
  if( !StartTransfer(FALSE) )
  {
    while(1);
  }
  TransmitOneByte(0xD0);  //slave address
  TransmitOneByte(0x00); //register pointer pointing to first register 
  TransmitOneByte(0x00); //seconds  value
  TransmitOneByte(0x56); //min value
  TransmitOneByte(0x12); //hr value
  StopTransfer(); //I2C Stop
  if(!Success)
  {
     while(1);
  }
  while(1)
  {
    RTC_read();
    **//sending time to UART**
    putsUART1("Time: ");
    putsUART1(value6);
    putsUART1(value5);
    putsUART1(":");
    putsUART1(value4);
    putsUART1(value3);
    putsUART1(":");
    putsUART1(value2);
    putsUART1(value1);
    putsUART1("\n");
   }
}

**///******** FUNCTION TO READ FROM I2C ****************//**
void RTC_read()
 {

  StartTransfer(FALSE); //I2C Start
  TransmitOneByte(0xD0); //I2C slave address
  TransmitOneByte(0x00);
  StopTransfer(); //I2C Stop

 IdleI2C2(); //i2C Stop

 StartTransfer(TRUE);    //I2C Restart
 TransmitOneByte(0xD1);  //Slave address to read
 **//Reading from I2C slave**
 if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
 {
  putsUART1("Error: I2C Receive Overflow1\n");
 }
 else
 {
    **//read sec**
   while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
   Nop();
   sec = I2CGetByte(EEPROM_I2C_BUS); 
   AckI2C2();
   while (!I2CAcknowledgeHasCompleted(I2C2));  

   **//read min**
   I2CReceiverEnable(EEPROM_I2C_BUS, TRUE);
   while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS)); 
   Nop();
   min = I2CGetByte(EEPROM_I2C_BUS);  
   AckI2C2();
   while (!I2CAcknowledgeHasCompleted(I2C2)); 

   **//read hr**
   I2CReceiverEnable(EEPROM_I2C_BUS, TRUE);
   while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS)); 
   Nop();
   hr = I2CGetByte(EEPROM_I2C_BUS);  
   NotAckI2C2();
   while (!I2CAcknowledgeHasCompleted(I2C2)); 

 }

 StopTransfer(); //I2C Stop
 if(!Success)
 {
    while(1);
 }

    **//converting sec to ASCII**
    x1 = sec & 0x0F;
    p1 = x1 | 0x30;
    y = sec & 0xF0;
    y = y >> 4;
    p2 = y | 0x30;

    sprintf(value1,"%c",p1);
    sprintf(value2,"%c",p2);

    **///converting min to ASCII**
    x2 = min & 0x0F;
    p3 = x2 | 0x30;
    y2 = min & 0xF0;
    y2 = y2 >> 4;
    p4 = y2 | 0x30;
    sprintf(value3,"%c",p3);
    sprintf(value4,"%c",p4);

    **////converting hr to ASCII**
    x3 = hr & 0x0F;
    p5 = x3 | 0x30;
    y3 = hr & 0xF0;
    y3 = y3 >> 4;
    p6 = y3 | 0x30;
    sprintf(value5,"%c",p5);
    sprintf(value6,"%c",p6);

}

EDIT

Following are the functions used in code:

StartTransfer(BOOL restart):-

//Description:This routine starts (or restarts) a transfer to/from the EEPROM, waiting (in a blocking loop) until the start (or re-start) condition has completed.

 //Parameters:restart - If FALSE, send a "Start" condition
         //         - If TRUE, send a "Restart" condition

 //Returns: TRUE    - If successful
  //         FALSE   - If a collision occured during Start signaling


BOOL StartTransfer( BOOL restart )
{
I2C_STATUS  status;

// Send the Start (or Restart) signal
if(restart)
{
    I2CRepeatStart(EEPROM_I2C_BUS);
}
else
{
    // Wait for the bus to be idle, then start the transfer
    while( !I2CBusIsIdle(EEPROM_I2C_BUS) );

    if(I2CStart(EEPROM_I2C_BUS) != I2C_SUCCESS)
    {
        DBPRINTF("Error: Bus collision during transfer Start\n");
        return FALSE;
    }
}

// Wait for the signal to complete
do
{
    status = I2CGetStatus(EEPROM_I2C_BUS);

} while ( !(status & I2C_START) );

return TRUE;
}

BOOL TransmitOneByte( UINT8 data ):-

 //Description:This transmits one byte to the EEPROM, and reports errors for any bus collisions.
//Returns:TRUE    - Data was sent successfully
          FALSE   - A bus collision occured

BOOL TransmitOneByte( UINT8 data )
{
// Wait for the transmitter to be ready
while(!I2CTransmitterIsReady(EEPROM_I2C_BUS));

// Transmit the byte
if(I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
{
    DBPRINTF("Error: I2C Master Bus Collision\n");
    return FALSE;
}

// Wait for the transmission to finish
while(!I2CTransmissionHasCompleted(EEPROM_I2C_BUS));

return TRUE;
}

void StopTransfer( void ):-

 //Description:This routine Stops a transfer to/from the EEPROM, waiting (in //a blocking loop) until the Stop condition has completed.

void StopTransfer( void )
{
I2C_STATUS  status;

// Send the Stop signal
I2CStop(EEPROM_I2C_BUS);

// Wait for the signal to complete
do
{
    status = I2CGetStatus(EEPROM_I2C_BUS);

} while ( !(status & I2C_STOP) );
}

Best Answer

You only have to set time once and then just read it.

So next time don't include the setting time function in your code because earlier you have set time. The registers of DS1307 will contain the updated time and you will have to read it.

Lets say, you have below functions:

RTC_init     : to initialise I2C channel
RTC_setTime  : to set time
RTC_readTime : to read time

Then at first include all the three functions in your code. Something like below:

main()
{
  RTC_init();
  RTC_setTime();

  while(1)
  {
    RTC_readTime();
  }
}

and then second time, comment out the function RTC_setTime() and again program your device. Like below

main()
{
  RTC_init();
  //RTC_setTime();

  while(1)
  {
    RTC_readTime();
  }
}

Now if you didn't give power to your device, the battery will help DS1307 to hold the updated values of time & date to their registers and it will keep on doing this.