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.

RTC interfacing with 16F877a

Status
Not open for further replies.

varunme

Advanced Member level 3
Joined
Aug 10, 2011
Messages
741
Helped
17
Reputation
36
Reaction score
17
Trophy points
1,318
Activity points
5,764
RTC interfacing with proteus, yeilds no display of time on lcd, didnt checked on real hardware


code used is

Code:
unsigned char sec, min1, hr, week_day, day, mn, year;
char *txt, tnum[3];

// LCD module connections
sbit LCD_RS at RD2_bit;  // for writing to output pin always use latch (PIC18 family)
sbit LCD_EN at RD3_bit;  // for writing to output pin always use latch (PIC18 family)
sbit LCD_D4 at RD4_bit;  // for writing to output pin always use latch (PIC18 family)
sbit LCD_D5 at RD5_bit;  // for writing to output pin always use latch (PIC18 family)
sbit LCD_D6 at RD6_bit;  // for writing to output pin always use latch (PIC18 family)
sbit LCD_D7 at RD7_bit;  // for writing to output pin always use latch (PIC18 family)

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections


void Zero_Fill(char *value) {    // fill text repesentation
  if (value[1] == 0) {           //      with leading zero
    value[1] = value[0];
    value[0] = 48;
    value[2] = 0;
  }
}//~

//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
  I2C1_Start();
  I2C1_Wr(0xD0);
  I2C1_Wr(0);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1);
  *sec =I2C1_Rd(1);
  *min =I2C1_Rd(1);
  *hr =I2C1_Rd(1);
  *week_day =I2C1_Rd(1);
  *day =I2C1_Rd(1);
  *mn =I2C1_Rd(1);
  *year =I2C1_Rd(0);
  I2C1_Stop();
}//~

//-------------------- Formats date and time
void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
  *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
  *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
  *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
  *week_day =(*week_day & 0x07);
  *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
  *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
  *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}//~

//-------------------- Output values to LCD
void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {
   switch(week_day){
     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_Chr(1, 6, (day / 10)   + 48);    // Print tens digit of day variable
   Lcd_Chr(1, 7, (day % 10)   + 48);    // Print oness digit of day variable
   Lcd_Chr(1, 9, (mn / 10) + 48);
   Lcd_Chr(1,10, (mn % 10) + 48);
   Lcd_Chr(1,15,  year  + 48);          // Print year vaiable + 8 (start from year 2008)

   Lcd_Chr(2, 6, (hr / 10)   + 48);
   Lcd_Chr(2, 7, (hr % 10)   + 48);
   Lcd_Chr(2, 9, (min / 10) + 48);
   Lcd_Chr(2,10, (min % 10) + 48);
   Lcd_Chr(2,12, (sec / 10) + 48);
   Lcd_Chr(2,13, (sec % 10) + 48);

}//~

//------------------ Performs project-wide init
void Init_Main() {

  ADCON1 |= 0x0F;            // Configure AN pins as digital
  CMCON  |= 7;               // Disable comparators

  I2C1_Init(100000);         // Initialize Soft I2C communication

  Lcd_Init();                // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
  Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off

  LCD_Chr(1,8,'.');
  LCD_Chr(1,11,'.');
  txt = "Time:";
  LCD_Out(2,1,txt);
  LCD_Chr(2,8,':');
  LCD_Chr(2,11,':');
  txt = "200";
  Lcd_Out(1,12,txt);
  LCD_Cmd(_LCD_CURSOR_OFF);
}

//----------------- Main procedure
void main() {
  Init_Main();               // Perform initialization

  while (1) {                // Endless loop
    Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);      // read time from RTC(DS1307)
    Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year); // format date and time
    Display_Time(sec, min1, hr, week_day, day, mn, year);    // prepare and display on LCD
    Delay_ms(1000);                                          // wait 1s
  }
}
 

Attachments

  • RTC.png
    RTC.png
    27.7 KB · Views: 115

You have not shown I2C1_Rd(); function in above program.

One advice for you to use single read command instead of Repeated start command.

Focus to write address of register and than read back, than again give address of second register and read back. You have to do this by making a function after I2C start with I2C_reg_address, than read
 

varunme said:
RTC interfacing with proteus, yeilds no display of time on lcd, didnt checked on real hardware
I think you are missing pull up resistors on SDA and SCL lines.

Hope that helped.
Alexandros
 

I added pullups on SDA and SCL, but now too its not working
 

Attachments

  • RTC2.png
    RTC2.png
    32 KB · Views: 94
Last edited:

I added pullups on SDA and SCL, but now too its not working

I think that the RTC cannot work with its VBAT pin unconnected. Try giving 3V on this pin.
Furthermore, make sure you are using 32.768kHz quartz crystal with specified load capacitance (CL) of 12.5pF.
 

Added 3V now too no luck

A working example using another processor is attached
 

Attachments

  • RTC 3.png
    RTC 3.png
    43.8 KB · Views: 98

I could made it work in real hardware, but cant in the proteus, dont know why...
 

The xtal value is not defined i think.

Remove the crytsal and try
 

yes, removed xtal and tried also

Now i discovered that , in real hardware also, some problems like i doesnot update time every second and some values inside time also not correct.

ABCD0001.JPG
 

You have not shown I2C1_Rd(); function in above program.
One advice for you to use single read command instead of Repeated start command.
Focus to write address of register and than read back, than again give address of second register and read back. You have to do this by making a function after I2C start with I2C_reg_address, than read
can u give an example ?
 

At first you need to write current date/time/calender data to RTC than enable RTC by pulsing 7th Bit of Address '0'h, after this.

The good thing to read only few addresses all time, and those variable which update at every 12:00 Am read them at that time or at every specific time, let say 1 or 2 hour.

Try to read only Time register all the time and rest all register at specific time. The problem you are getting is due to long communication established for every second.

Use this flowchart.

At start of module read all register, after that only read time registers nd when date change occur (which is at 12:000 am) read all other register again for update.

The main reason you are not getting right characters, is in your program. Re-adjust your your comparing function, which compare resulting data to obtain real number? for troubleshooting do one thing, show your strange result directly on LCD and check your mistake in comparing function.

Hope this may help you
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
At first you need to write current date/time/calender data to RTC than enable RTC by pulsing 7th Bit of Address '0'h, after this.
The good thing to read only few addresses all time, and those variable which update at every 12:00 Am read them at that time or at every specific time, let say 1 or 2 hour.
Try to read only Time register all the time and rest all register at specific time. The problem you are getting is due to long communication established for every second.
Use this flowchart.
At start of module read all register, after that only read time registers nd when date change occur (which is at 12:000 am) read all other register again for update.
The main reason you are not getting right characters, is in your program. Re-adjust your your comparing function, which compare resulting data to obtain real number? for troubleshooting do one thing, show your strange result directly on LCD and check your mistake in comparing function.
Hope this may help you
can you provide me with such kind of working example ?
 

can you provide me with such kind of working example ?

A working example :-D, its really difficult to write code for you now. However, i shall write a program flow for you right now.

At start of program
Declare all TIME and Other Registers.
Declare one unsigned char (let say update, and set to ZERO value)
Read RTC Time and all Register, store them in defined characters arrays and process them and display them.

Read time registers only, and update LCD
Than check Time using IF ELSE, if HOUR found ZERO for 24h and 12AM for 12h. It means you need to update all other register now, check update char, like below Example, Code your program like this by your own

Start of Main Program
READ all TIME DATE and OTHER Registers and update LCD
While(1)
{

READ RTC Time Only and Update LCD
IF(Time==12AM)
{
IF (update == 0)
{
READ all TIME DATE and OTHER registers and update LCD. and change value of update.
update = 1;
}
}

IF(Time>12AM)
{
update = 0;
}

}
 

is the comparing function, this function ?

Code:
void Zero_Fill(char *value) {    // fill text repesentation
  if (value[1] == 0) {           //      with leading zero
    value[1] = value[0];
    value[0] = 48;
    value[2] = 0;
  }
}//~


---------- Post added at 06:21 ---------- Previous post was at 06:17 ----------

or the transform function ?

Code:
//-------------------- Formats date and time
void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
  *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
  *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
  *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
  *week_day =(*week_day & 0x07);
  *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
  *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
  *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}//~
 

is the comparing function, this function ?

Code:
void Zero_Fill(char *value) {    // fill text repesentation
  if (value[1] == 0) {           //      with leading zero
    value[1] = value[0];
    value[0] = 48;
    value[2] = 0;
  }
}//~


---------- Post added at 06:21 ---------- Previous post was at 06:17 ----------

or the transform function ?

Code:
//-------------------- Formats date and time
void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
  *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
  *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
  *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
  *week_day =(*week_day & 0x07);
  *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
  *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
  *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}//~

The code example i have wrote is for your idea, you have to write your own comparing code by help of my code idea. The above shown code are not that one you required
 

you said, i have to adjust the comparing function, which is the comparing function, is it transform function ?, or i have to make a new compare function with if statement ?

and how can i check

IF(Time==12AM)

how the time variable is stored ?
 

you said, i have to adjust the comparing function, which is the comparing function, is it transform function ?, or i have to make a new compare function with if statement ?

and how can i check

IF(Time==12AM)

how the time variable is stored ?

You are handling Time with unsigned char hr in 24H mode, so make a function to check hr value, if it is 00 than do the rest i told earlier. it should be like this

IF(hr==0x00)
{
}
 
  • Like
Reactions: varunme

    varunme

    Points: 2
    Helpful Answer Positive Rating
I have attached the modified code, please find mistakes in it
 

Attachments

  • RTC mast.txt
    5.4 KB · Views: 68

You have change these code to work properly,

Read_Time2(&sec,&min1,&hr,&week_day,&day,&mn,&year); // read time from RTC(DS1307)
Transform_Time2(&sec,&min1,&hr,&week_day,&day,&mn,&year); // format date and time
Display_Time(sec, min1, hr, week_day, day, mn, year);

in Read_Time2 you only need to read Hr, min and sec, and same changes will be require for Transfer function, Display fuinction will be remain, as it will display old values and update all of them at 24th hour,
 

I updated all,
clock is ticking but year has unrecognized chars
I think the problem is with
year = ((year & 0xf0) >> 4)*10 + (year & 0x0F); // Transform year

---------- Post added at 08:09 ---------- Previous post was at 07:31 ----------

It stops after one or two ticking
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top