DS1307 Rtc Problem

Thread Starter

PIYUSH SONI

Joined Nov 15, 2013
32
Hello, everyone.
I am trying to display date & time from RTC Ds1307 on LCD using Pic 18f4520 MCU. I have also connected a push button on PORTA and by pressing it Time & date should display.

Sometime i get garbage value but most time nothing at all.
I have attached my code guys. PLEASE go through it & Kindly HELP me.
Rich (BB code):
// Lcd module connections
sbit LCD_RS at LATB0_bit;
sbit LCD_EN at LATB1_bit;
sbit LCD_D4 at LATB2_bit;
sbit LCD_D5 at LATB3_bit;
sbit LCD_D6 at LATB4_bit;
sbit LCD_D7 at LATB5_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;

// Lcd constants
char txt1[] = "SPG INFOTECH";
char txt2[] = "DIGITAL CLOCK";
char txt3[] = "DATE:";
char txt4[] = "TIME:";

// Module variables
unsigned char hours, minutes, seconds, day, week, month, year;    // Global date/time variables
char oldstate = 0;



// RTC Definitions
#define RTC_ADDR  0xD0

/**************************************************************************************************
* DS1307 Functions
**************************************************************************************************/

/**************************************************************************************************
* Read data from RTC DS1307
* input : addres of RTC register
* output: value of of RTC register
**************************************************************************************************/
unsigned char RTC_Read(unsigned char addr){
  unsigned char value;

  I2C1_Start();                   // Issue start signal
  I2C1_Wr(RTC_ADDR);              // Address DS1307, see DS1307 datasheet
  I2C1_Wr(addr);                  // Start from address 2
  I2C1_Start();                   // Issue repeated start signal
  I2C1_Wr(RTC_ADDR);              // Address DS1307 for reading R/W=1

  value = I2C1_Rd(0);             // Read seconds byte
  I2C1_Stop();                    // Issue stop signal

  return value;
}

/**************************************************************************************************
* Write data from DS1307
* input : addres of RTC register, value of of RTC register
**************************************************************************************************/
void RTC_Write(unsigned char addr, unsigned char value){
  I2C1_Start();         // Issue start signal
  I2C1_Wr(RTC_ADDR);    // Address DS1307
  I2C1_Wr(addr);        // Start from address
  I2C1_Wr(value);       // Write value to RTC register
  I2C1_Stop();          // Issue stop signal
}

/**************************************************************************************************
* Read time from RTC DS1307
* input : pointer to variables where RTC data will be stored
* output: variables with RTC data
**************************************************************************************************/
void Read_Time(unsigned char *p_hours, unsigned char *p_minutes, unsigned char *p_seconds,
               unsigned char *p_day, unsigned char *p_week, unsigned char *p_month, unsigned char *p_year){
  I2C1_Start();                // Issue start signal
  I2C1_Wr(RTC_ADDR);           // Address DS1307, see DS1307 datasheet
  I2C1_Wr(0);                  // Start from address 0
  I2C1_Repeated_Start();       // Issue repeated start signal
  I2C1_Wr(RTC_ADDR + 1);       // Address DS1307 for reading R/W=1

  *p_seconds = I2C1_Rd(1);     // Read seconds byte
  *p_minutes = I2C1_Rd(1);     // Read minutes byte
  *p_hours = I2C1_Rd(1);       // Read hours byte
  *p_week =I2C1_Rd(1);
  *p_day =I2C1_Rd(1);
  *p_month =I2C1_Rd(1);
  *p_year =I2C1_Rd(0);

  I2C1_Stop();                 // Issue stop signal
}

/**************************************************************************************************
* Write time to RTC DS1307
* input : variables with RTC data
**************************************************************************************************/
void Write_Time(unsigned char c_hours, unsigned char c_minutes, unsigned char c_seconds,
                unsigned char c_day, unsigned char c_week, unsigned char c_month, unsigned char c_year){
   I2C1_Start();                     // issue start signal
   I2C1_Wr(RTC_ADDR);                // address DS1307
   I2C1_Wr(0);                       // start from word at address (REG0)
   I2C1_Wr(0x80);                    // write $80 to REG0. (pause counter + 0 sec)

   I2C1_Wr(c_minutes);               // write 0 to minutes word to (REG1)
   I2C1_Wr(c_hours);                 // write 17 to hours word (24-hours mode)(REG2)
   I2C1_Wr(c_week);                  // write 2 - Monday (REG3)
   I2C1_Wr(c_day);                   // write 4 to date word (REG4)
   I2C1_Wr(c_month);                 // write 5 (May) to month word (REG5)
   I2C1_Wr(c_year);                  // write 01 to year word (REG6)
   I2C1_Stop();                      // issue stop signal

   I2C1_Start();                     // issue start signal
   I2C1_Wr(RTC_ADDR);                // address DS1307
   I2C1_Wr(0);                       // start from word at address 0
   I2C1_Wr(0 | c_seconds);           // write 0 to REG0 (enable counting + 0 sec)
   I2C1_Stop();                      // issue stop signal
}
/**************************************************************************************************
* Show on the LCD display
* input : variables with RTC data
**************************************************************************************************/
void Show_Time(){
  char *txt;

  seconds  =  ((seconds & 0x70) >> 4)*10 + (seconds & 0x0F);
  minutes  =  ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F);
  hours    =  ((hours & 0x30) >> 4)*10 + (hours & 0x0F);
  week     =  (week & 0x07);
  day      =  ((day & 0xF0) >> 4)*10 + (day & 0x0F);
  month    =  ((month & 0x10) >> 4)*10 + (month & 0x0F);
  year     =  ((year & 0xF0)>>4)*10+(year & 0x0F);

  switch(week)
  {
    case 1: txt="Sun"; break;
    case 2: txt="Mon"; break;
    case 3: txt="Tue"; break;
    case 4: txt="Wed"; break;
    case 5: txt="Thu"; break;
    case 6: txt="Fri"; break;
    case 7: txt="Sat"; break;
  }

  /*LCD_Out(1,1, txt);*/
  Lcd_Out(1, 6, (day / 10)   + 48);    // Print tens digit of day variable
  Lcd_Out(1, 7, (day % 10)   + 48);    // Print oness digit of day variable
  Lcd_Out(1, 9, (month / 10) + 48);
  Lcd_Out(1,10, (month % 10) + 48);
  Lcd_Out(1,14, (year / 10)  + 48);
  Lcd_Out(1,15, (year % 10)  + 48);

  Lcd_Out(2, 6, (hours / 10)   + 48);
  Lcd_Out(2, 7, (hours % 10)   + 48);
  Lcd_Out(2, 9, (minutes / 10) + 48);
  Lcd_Out(2,10, (minutes % 10) + 48);
  Lcd_Out(2,12, (seconds / 10) + 48);
  Lcd_Out(2,13, (seconds % 10) + 48);
}

/**************************************************************************************************
* MAIN PROGRAM
**************************************************************************************************/
void main(){
 ADRESL = 0;
ADRESH = 0;
CMCON =7;
PORTA = 0;
TRISA =1;
LATA=1;
ADCON0 =0;
ADCON1 =0;
ADCON2 = 0;
TRISA = 0b00000111;
PORTD = 0;
  I2C1_Init(100000);                 // Initialize I2C bus for communication with RTC
  Lcd_Init();                        // Initialize Lcd

  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
  Lcd_Out(1,1,txt1);                 // Write text in first row
  Lcd_Out(2,4,txt2);                 // Write text in second row

  Delay_ms(2000);                    // delay 2 sec

  Lcd_Cmd(_LCD_CLEAR);               // Prepare and output static text on LCD
  LCD_Chr(1,8,'.');
  LCD_Chr(1,11,'.');
  LCD_Out(2,1,txt3);
  LCD_Out(1,1,txt4);
  LCD_Chr(2,8,':');
  LCD_Chr(2,11,':');
  LCD_Out(1,12,"20");

 // Start the test examples
  while(1){                           // Endless loop
    if (Button(&PORTA, 1, 1, 1)) {               // Detect logical one
      oldstate = 1;                              // Update flag
    }
    if (oldstate && Button(&PORTA, 1, 1, 0)) {   // Detect one-to-zero transition
// Write TIME    11  : 15  : 00  : 24.  tuesday april  2012
      Write_Time(0x11, 0x15, 0x00, 0x24, 0x03,   0x04, 0x12);
      oldstate = 0;                             // Update flag
    }


    Read_Time(&hours, &minutes, &seconds, &day, &week, &month, &year);
    Show_Time();
    Delay_mS(10);
  }
    }


/**************************************************************************************************
* End of File
 

ErnieM

Joined Apr 24, 2011
8,377
If the time will not update faster then, ohh, say, once a second, why do you try to update every 10 milliseconds? While you provide little info on your specific problem it could just be you are updating the screen so fast there isn't time for anything to appear.

Otherwise, break the problem down: display test data, not DS1307 data but data you create. Then read the DS1307 and look at the results on your in-circuit debugger.

Once they both work, stitch together and enjoy the timeless quality of your new clock.

Also, what compiler are you using? I've seen XC8 do so poorly doing pointers I stopped using it for a while. You over and over pass the time variables as pointers, but as they are global variables anyway they are already shared and don't need to be passed at all.
 

spinnaker

Joined Oct 29, 2009
7,830
You are going to have to put a whole lot more effort into this on your own if you want help.

First off what does "Sometime i get garbage value but most time nothing" mean?

Have you confirmed that your LCD code is working properly by trying to display some static message such as "Hello World" ? If you have not then start there. Don't worry about the RTC values yet.
 

THE_RB

Joined Feb 11, 2008
5,438
It looks like you are using MikroC compiler?

I thought it already has functions for using the Dallas DTC 1-wire clock?

MikroE sell a Dallas 1-wire clock module, so I'm sure they have source code already working for that IC. :)
 

Thread Starter

PIYUSH SONI

Joined Nov 15, 2013
32
Hi, Erniem.
Are u telling me to give 1sec delay... I am using mikroCpro and i am not getting you about breaking the problem down.
Can you explain me.
Thanks.
 

spinnaker

Joined Oct 29, 2009
7,830
Hi, Erniem.
Are u telling me to give 1sec delay... I am using mikroCpro and i am not getting you about breaking the problem down.
Can you explain me.
Thanks.
The same thing that I wrote. Do not try to work on the whole problem at the same time.


1. Get something simple displayed on your LCD, like "Hello".

once that works

2. Use your debugger and investigate the results that you get back from the sensor.

Once you know you are getting a value back and understand how to convert move on to displaying it on the LCD.

You are trying to do too much all at once. If you break the problem down into small pieces then it will be much easier to understand and for others to help you.
 

Thread Starter

PIYUSH SONI

Joined Nov 15, 2013
32
ok i got it spinnaker. I am able to display the text part on LCD "SPG INFOTECH" , "Digital clock", "DATE:" & "TIME" .
These all are displaying. Only the clock part is not diplaying.
I don't know the problem behind it..Can you...?
Thanks for ur cooperation.
 

spinnaker

Joined Oct 29, 2009
7,830
ok i got it spinnaker. I am able to display the text part on LCD "SPG INFOTECH" , "Digital clock", "DATE:" & "TIME" .
These all are displaying. Only the clock part is not diplaying.
I don't know the problem behind it..Can you...?
Thanks for ur cooperation.
That is good. Now use your debugger and see what value you are getting from the RTC.
 
Top