1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Master Slave Clocks with PIC16F887

Discussion in 'Microcontrollers' started by koolguy, Mar 31, 2015.

  1. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    it is not working i think internal osc is not working, what you think??
    PORTB=data[i%16];
    1 // only

    PORTB=data[i>>4];
    un numerical data
     
  2. MCU88

    MCU88 Member

    Joined:
    Apr 1, 2015
    Messages:
    121
    Likes:
    7
    Perhaps someone should start off with a much less ambitious project such as an LED roulette wheel. No perhaps an decision maker with 4 LEDs. One for "yes", "no", "maybe" and "definitely" ...
     
  3. MCU88

    MCU88 Member

    Joined:
    Apr 1, 2015
    Messages:
    121
    Likes:
    7
    I think you are driving Ian bonkers trying to help you.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9

    So, you think it is difficult project?
    anyway what you do sir?​
     
  6. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    And some!!!!

    What I don't get, is why bother using a library, then just dismissing it completely.

    Once you include the I2C library all you need to do is use the Read and Write functions..

    No stop, start, ack, nack.... Just ReadRtc and WriteRtc.... its not rocket science...
     
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    If you look at post #65

    In the while loop I use ReadClock(&time[0]); This contains everything to put all the time into the time[] array..

    Then I display them.... just take a bit of time and run through it!!!!
     
  8. MCU88

    MCU88 Member

    Joined:
    Apr 1, 2015
    Messages:
    121
    Likes:
    7
    I think it is perhaps not for you if you lack basic computer programming understanding. What do I do? Well I would like to open an electronics shop and sell parts and offer custom engineering services. Perhaps if I get too busy I can bring some jobs to this forum...
     
  9. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    that good...!!
     
  10. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    In #65
    There is delay two function what is the use of it??
    and
    Code (C):
    //Sends the start and device address.
    //If the device is busy then it resends until accepted.
    void SendID(char DeviceID)
       {
       SendStart();
       if(SendByte(DeviceID)==1)     // Send ID until accepted..
         return;
       do
         {
         SendRestart();
         }while(SendByte(DeviceID)==0);
       }
     
    sendbytes what is this?


    Code (C):
    //Write a byte to The RTC
    char WriteRTC(char Address, char Byte)
       {
       SendID(0b11010000);         // Send 0xD0
       if(SendByte(Address&0xff)==0)   // Send address
         return(0);
       if(SendByte(Byte)==0)       // Send byte
         return(0);
       SendStop();             // All done
       return(1);
       }

    Code (C):
     ReadClock(&Time[0]);               // Get time ( BCD format as
         delayMs(250);                   // we are using  7 seg )
         DISP[5] = Time[2]>>4; DISP[4] = Time[2] & 0xf;   // fill display buffer
         DISP[3] = Time[1]>>4; DISP[2] = Time[1] & 0xf;   // backwards so it's
         DISP[1] = Time[0]>>4; DISP[0] = Time[0] & 0xf;   // readable...
    how it is working i want only min and hour !
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    Forget the two functions SendID() and WiteRTC().... They are low level.... All you need concern yourself with is ReadClock().. you call that routine periodically then Time[0] = seconds.. Time[1] = minutes and Time[2] = Hours..

    If you are working on a real board you will need to initiate the clock..

    To do this write this..

    unsigned char Time[] = {0, 43 , 16, 0 , 10, 4, 15}; Instead of whats there.. FYI ( 16:43 10/04/2015 my time here )

    Then add WriteClock(&Time[0]); before the while loop.... To set the time
     
  12. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    The main problem in my code i posted earlier is the ds1307 is not updating he sec in it, why?
    is the i2c speed freq is to fast??
    because i am directly reading the bits in i by PORTB=i;

     
  13. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    What that this mean?
    it should be deleted?

    Forget the two functions SendID() and WiteRTC().... They are low level....
     
  14. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    its not updating showing 0 0 8 only

    Code (C):
    #include <htc.h>

    __CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
    #define _XTAL_FREQ 20000000
    #define SDATA RC4
    #define SCLK RC3
    void InitI2C(),I2C_start(void),I2C_write(char x), I2cSTOP(void);  
    void i2c_Wait(void);
    unsigned char DISP[3];
    unsigned char Time[] = {01, 11 ,33, 22 , 10, 4, 15};
    unsigned char digits[] = {  0b00010000,0b01111101,0b00100011,0b00101000,0b01001101,0b10001000,
    0b10000000, 0b00111101,0X00,0b00001000};

    void InitI2C()
       {
       TRISC3=1;
       TRISC4=1;
       SSPCON=0b00101000;
       SSPCON2=0;
       SSPSTAT=0b10000000;
       SSPADD=50;  //20000/(4*100);  //Fosc/(4*baud)
       SSPIF=0;
       BCLIF=0;
       }


    void WaitSSP()
       {
       while(SSPIF==0);
       SSPIF=0;
       }


    void SendStart()
       {
       SEN=1;
       WaitSSP();
       }

    void SendStop()
       {
       PEN=1;
       WaitSSP();
       }


    void SendRestart()
       {
       RSEN=1;
       WaitSSP();
       }


    char SendByte(char Byte)
       {
       SSPBUF=Byte;
       WaitSSP();
       return(!ACKSTAT);
       }


    char ReceiveByte()
       {
       RCEN=1;         // get byte
       WaitSSP();
       return(SSPBUF);
       }


    void SendNack()
       {
       ACKDT=1;       // Not Acknowledge
       ACKEN=1;
       WaitSSP();
       }


    void SendAck()
       {
       ACKDT=0;       // Acknowledge
       ACKEN=1;
       WaitSSP();
       }

    void SendID(char DeviceID)
       {
       SendStart();
       if(SendByte(DeviceID)==1)     // Send ID until accepted..
         return;
       do
         {
         SendRestart();
         }while(SendByte(DeviceID)==0);
       }


    char ReadRTC(char Address)
       {
       char Byte;
       SendID(0b11010000);         // Send 0xD0
      if(SendByte(Address&0xff)==0)   // Send address
         return(0);
       SendRestart();           // Re-start
       if(SendByte(0b11010001)==0)     // Read 0xD1
         return(0);
       Byte=ReceiveByte();         // Get byte
       SendNack();             // No more
       SendStop();             // Stop bus
       return(Byte);           // All done
       }

    void WriteClock(char *array)       // Not used
       {
       char x;
       int tmp;
       for(x=0;x<7;x++)
         {
         tmp = array[x] / 10;
         tmp << = 4;
         tmp += array[x] % 16;
         WriteRTC(x,tmp);
         }
       }

    void ReadClock(char *array)
       {
       char x;
       for(x=0;x<7;x++)
         array[x] = ReadRTC(x);       // No need to BCD-BIN
       }



               
    void main(void)
       {
    ANSELH = 0;
        TRISC3=1; //direction to input have be changed
        TRISC4=1;

    RD0=0;
    RD1=0;
    RD2=0;
    RD3=0;
    TRISB=0X00;
    TRISD=0X00;
    PORTB=0B00000000;
    unsigned char ch=0;
    unsigned char i=0;
       int idx;          
       unsigned char DIGIT;       // A temporary store for manipulation
       TRISC = 0;             // portc tris bits
       TRISD = 0;             // portd tris bits
      InitI2C();
     
       while(1)
         {
         ReadClock(&Time[0]);            
         __delay_ms(250);                  
       
        DISP[2] = Time[1] & 0xf;  
         DISP[1] = Time[0]>>4; DISP[0] = Time[0] & 0xf;  
       
    RD0=1;
    RD1=0;
    RD2=0;
    RD3=0;

           PORTB = digits[DISP[0]];         // retrive 7 seg code
           __delay_ms(250);
    RD0=0;
    RD1=1;
    RD2=0;
    RD3=0;

           PORTB = digits[DISP[1]];         // retrive 7 seg code
           __delay_ms(250);

    RD0=0;
    RD1=0;
    RD2=1;
    RD3=0;

           PORTB = digits[DISP[2]];         // retrive 7 seg code

           __delay_ms(250);


         



     
         }
     
       }

     
     
  15. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    Code (c):

    #include <htc.h>

    __CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
    #define _XTAL_FREQ 20000000
    #define SDATA RC4
    #define SCLK RC3
    void InitI2C(),I2C_start(void),I2C_write(char x), I2cSTOP(void);  
    void i2c_Wait(void);
    unsigned char DISP[3];
    unsigned char Time[] = {01, 0x11 ,0x3, 0x22 , 0x10, 0x4, 0x15};
    unsigned char digits[] = {  0b00010000,0b01111101,0b00100010,0b00101000,0b01001101,0b10001000,
    0b10000000, 0b00111101,0X00,0b00001000};

    void InitI2C()
      {
      TRISC3=1;
      TRISC4=1;
      SSPCON=0b00101000;
      SSPCON2=0;
      SSPSTAT=0b10000000;
      SSPADD=50;  //20000/(4*100);  //Fosc/(4*baud)
      SSPIF=0;
      BCLIF=0;
      }

    void WaitSSP()
      {
      while(SSPIF==0);
      SSPIF=0;
      }

    void SendStart()
      {
      SEN=1;
      WaitSSP();
      }

    void SendStop()
      {
      PEN=1;
      WaitSSP();
      }


    void SendRestart()
      {
      RSEN=1;
      WaitSSP();
      }

    char SendByte(char Byte)
      {
      SSPBUF=Byte;
      WaitSSP();
      return(!ACKSTAT);
      }


    char ReceiveByte()
      {
      RCEN=1;  // get byte
      WaitSSP();
      return(SSPBUF);
      }

    void SendNack()
      {
      ACKDT=1;  // Not Acknowledge
      ACKEN=1;
      WaitSSP();
      }

    void SendAck()
      {
      ACKDT=0;  // Acknowledge
      ACKEN=1;
      WaitSSP();
      }

    void SendID(char DeviceID)
      {
      SendStart();
      if(SendByte(DeviceID)==1)  // Send ID until accepted..
      return;
      do
      {
      SendRestart();
      }while(SendByte(DeviceID)==0);
      }

    //Write a byte to The RTC
    char WriteRTC(char Address, char Byte)
      {
      SendID(0b11010000);  // Send 0xD0
      if(SendByte(Address&0xff)==0)  // Send address
      return(0);
      if(SendByte(Byte)==0)  // Send byte
      return(0);
      SendStop();  // All done
      return(1);
      }

    char ReadRTC(char Address)
      {
      char Byte;
      SendID(0b11010000);  // Send 0xD0
      if(SendByte(Address&0xff)==0)  // Send address
      return(0);
      SendRestart();  // Re-start
      if(SendByte(0b11010001)==0)  // Read 0xD1
      return(0);
      Byte=ReceiveByte();  // Get byte
      SendNack();  // No more
      SendStop();  // Stop bus
      return(Byte);  // All done
      }

    void WriteClock(char *array)  // Not used
      {
      char x;
      int tmp;
      for(x=0;x<7;x++)
      {
      WriteRTC(x,array[x]);
      }
      }

    void ReadClock(char *array)
      {
      char x;
      for(x=0;x<7;x++)
      array[x] = ReadRTC(x);  // No need to BCD-BIN
      }



       
    void main(void)
      {
       unsigned char ch=0;
       unsigned char i=0;
       int idx;  
       unsigned char DIGIT;  // A temporary store for manipulation

       ANSELH = 0;
      TRISC3=1; //direction to input have be changed
      TRISC4=1;

       RD0=0;
       RD1=0;
       RD2=0;
       RD3=0;
       TRISB=0X00;
       TRISD=0X00;
       PORTB=0B00000000;
       
       TRISC = 0;  // portc tris bits
       TRISD = 0;  // portd tris bits
       InitI2C();
       WriteClock(&Time[0]);
       while(1)
         {
         ReadClock(&Time[0]);  
         __delay_ms(250);  
       
         DISP[2] = Time[1] & 0xf;  
         DISP[1] = Time[0]>>4; DISP[0] = Time[0] & 0xf;  
         
         PORTD = 1;
       
         PORTB = digits[DISP[0]];  // retrive 7 seg code
         __delay_ms(250);

         PORTD = 2;

         PORTB = digits[DISP[1]];  // retrive 7 seg code
         __delay_ms(250);

         PORTD = 4;

         PORTB = digits[DISP[2]];  // retrive 7 seg code

      __delay_ms(250);
      }
      }
     
    This works well!! Time and display....... your number 2 digit was wrong... I corrected it... Also there was some ReadModifyWrite crap going on so I changed the PORTD writes to suit!!!
     
  16. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    The pic kit 2 showing error...
     

    Attached Files:

  17. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    hello,
    I have changed the delat to 10mSec

    it start with
    001
    011
    .
    .
    591
    002...


    like this when micro power is off , the clock start from 000 it should internally work!
    while(1)
    {
    ReadClock(&Time[0]);
    __delay_ms(10);

    DISP[2] = Time[1] & 0xf;
    DISP[1] = Time[0]>>4; DISP[0] = Time[0] & 0xf;

    PORTD = 1;

    PORTB = digits[DISP[0]]; // retrive 7 seg code
    __delay_ms(10);

    PORTD = 2;

    PORTB = digits[DISP[1]]; // retrive 7 seg code
    __delay_ms(10);

    PORTD = 4;

    PORTB = digits[DISP[2]]; // retrive 7 seg code

    __delay_ms(10);
    }
    }
     
    Last edited: Apr 11, 2015
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    You're getting close....
     
    • Like Like x 1
  19. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    i think the WriteClock(&Time[0]); function is in main so, it must be writing again.
    so, how to once write the setting?
    and do you think the sec is working perfect in time??
     
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    909
    Location:
    Rochdale UK
    ONLINE
    The write clock function is BEFORE the while loop so it is executed once only... If the seconds keep resetting then the micro is resetting...

    On my simulator it works fine....
     
  21. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    The micro will reset after power off, but the DS1307 is running from battery backup!
    So, what to do to get accurate time after power off ?

    micro is resetting.
    How to avoid this??
     

Share This Page