RTC with PCF8583 and PIC16F877A in Microc

Status
Not open for further replies.

jean12

Advanced Member level 2
Joined
Aug 27, 2013
Messages
529
Helped
5
Reputation
12
Reaction score
6
Trophy points
18
www.ntigltd.com
Activity points
5,497
Hello there can anyone help me to see how the following codes can be used to display the clock on seven segment display, I tried many times with more technics but I am not succeeding to display the real time;I am using PCF8583 and PIC16F877A

Please help;see the code below and circuit

Code:
struct TTime {
  char year, month, day, hours, minutes, seconds;
} TimeRead;

      struct Wr_TTime {char year, month, day, hours, minutes, seconds;
} TimeToWrite;

char yearmod4, byteRead;

void Display_Time() {
unsigned  const digit[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
 char txt[4];

   TRISB=0;
   PORTB.RB1=0;
   PORTB.RB2=0;
   PORTB.RB3=0;
   PORTB.RB0=1;
   txt[0]=TimeRead.hours / 10;
   PORTD=digit[txt[0]];
   delay_us(5);
    //end first digit
   TRISB=0;
   PORTB.RB0=0;
   PORTB.RB2=0;
   PORTB.RB3=0;
   PORTB.RB1=1;
   txt[1]=TimeRead.hours % 10;
   PORTD=digit[txt[1]];
   delay_us(5);

   //end second digit
   TRISB=0;
   PORTB.RB1=0;
   PORTB.RB2=1;
   PORTB.RB3=0;
   PORTB.RB0=0;
   txt[2]=TimeRead.minutes / 10;
   PORTD=digit[txt[2]];
   delay_us(5);
   //end third digit

   TRISB=0;
   PORTB.RB1=0;
   PORTB.RB2=0;
   PORTB.RB3=1;
   PORTB.RB0=0;
   txt[3]=TimeRead.minutes % 10;
   PORTD=digit[txt[3]];
   delay_us(5);
   //end fourth digit
}


void ReadTime() {
char updateYear;

   updateYear = 0;

   I2C1_Start();                // issue start signal
   I2C1_Wr(0xA0);               // address PCF8583
   I2C1_Wr(2);                  // first word address
   I2C1_Repeated_Start();       // issue repeated start signal
   I2C1_Wr(0xA1);               // address PCF8583 for reading R/W=1


   byteRead = I2C1_Rd(1u);     // read minutes byte
   TimeRead.minutes = (byteRead >> 4)*10 + (byteRead & 0x0F); // transform minutes
   while (!I2C1_Is_Idle())
     asm nop;

   byteRead = I2C1_Rd(1u);     // read hours byte
   TimeRead.hours = (byteRead >> 4)*10 + (byteRead & 0x0F); // transform hours
   while (!I2C1_Is_Idle())
     asm nop;
   byteRead = I2C1_Rd(0u);     // read weekday/month byte
   TimeRead.month = ((byteRead & 0b00010000) >> 4)*10 + (byteRead & 0x0F); // transform month
   while (!I2C1_Is_Idle())
     asm nop;
   I2C1_Stop();

   I2C1_Start();                 // issue start signal
   I2C1_Wr(0xA0);               // address PCF8583
   I2C1_Wr(0x10);               // first word address
   I2C1_Repeated_Start();        // issue repeated start signal
   I2C1_Wr(0xA1);               // address PCF8583 for reading R/W=1

   byteRead = I2C1_Rd(0u);     // read year
   if (yearmod4 != byteRead % 4 ) { // check if year is incremented in RTC
       byteRead++;  // in this case the new value should be written to RTC RAM at address 16(0x10)
       updateYear = 1;
       }
   TimeRead.year = byteRead;

   while (!I2C1_Is_Idle())
     asm nop;
   I2C1_Stop();

   if (updateYear > 0) {
      I2C1_Start();            // issue start signal
      I2C1_Wr(0xA0);          // address PCF8530
      I2C1_Wr(0x10);          // start from word at address 16
      I2C1_Wr(TimeRead.year);         // write year to RAM
      I2C1_Stop();             // issue stop signal
      }
}
void MainInit() {

  CMCON = 0x07;
  I2C1_Init(100000);          // initialize I2C
}
void write_time(void)
  {
   TimeToWrite.hours   = 22;
   TimeToWrite.minutes = 10;
   I2C1_Start();            // issue start signal
   I2C1_Wr(0xA0);          // address PCF8583
   I2C1_Wr(0);            // start from word at address 0 (configuration word)
   I2C1_Wr(0x80);          // write 0x80 to config. (pause counter...)
   I2C1_Wr(0);            // write 0 to cents word
   I2C1_Wr(((TimeToWrite.minutes/10)<<4) + (TimeToWrite.minutes%10)); // write minutes word
   I2C1_Wr(((TimeToWrite.hours/10)<<4) + (TimeToWrite.hours%10)); // write hours word
   I2C1_Stop();             // issue stop signal

   I2C1_Start();            // issue start signal
   I2C1_Wr(0xA0);          // address PCF8530
   I2C1_Wr(0x10);          // start from word at address 16
   I2C1_Wr(TimeToWrite.year);         // write year to RAM
   I2C1_Stop();             // issue stop signal

   I2C1_Start();            // issue start signal
   I2C1_Wr(0xA0);           // address PCF8530
   I2C1_Wr(0);              // start from word at address 0
   I2C1_Wr(0);              // write 0 to config word (enable counting)
   I2C1_Stop();             // issue stop signal

   }
void main() {
     MainInit();
     write_time();
   while (1) {

     ReadTime();
     Display_Time();
     Delay_ms(1000);
     }
}

With those codes,the seven segments are flickering and not displaying the real time only 0 is displayed ,can you please help to solve those issue of flickering without using interrupts and also display the correct values on the seven segment.


View attachment share.bmp
 
Last edited by a moderator:

To avoid flickering you must use timer interrupt, and for shure avoid
Code:
Delay_ms(1000);

where may I use interrupts?do you mean the time used for multiplexing?can you please help me to handle this?Why the seven segment are not displaying good real time?only zeroes are flickering in the seven segment.

Please help.
 

Hey ,could you please help me to display using interrupts I don't know how to handle interrupts in Microc.

Thx,please help
 

Use help manual for this compiler and in isr routine update the display.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…