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

8051 with real time clock

Discussion in '8051/8951' started by Parth86, Apr 3, 2015.

  1. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    hello,
    I am making design on proteus software. I am interfacing RTC with 8051 and LED
    my task
    turn on LED for 30 second
    turn off lED for 1 minute
    turn on LED for 30 second
    turn off LED for 1 Hours
    turn on LED for 30 second
    turn off LED for 1 day
    upload_2015-4-4_23-52-18.png

    How to write c code for minute , day and also check circuit ?
    can someone explain with small example
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    First! Do not use the "RES" model for the SDA and SCL pullups!! The I2C won't work properly... Use the "PULLUP" resistor primitive.... You'll find it in the library.... I have posted ALL the low level C routines... They are for the SDCC compiler so you will have to change the defines to suit your compiler..

    You will need a BCD to Binary routine and one to swap back..

    BCD to binary

    Binary = BCD >> 4 * 10..
    Binary += BCD & 0xF..

    Binary to BCD

    BCD = Binary / 10 << 4..
    BCD += Binary % 10..

    Or if you are just using the values and not displaying them then just use BCD....
     

    Attached Files:

    • Like Like x 2
  3. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    What is "RES" model mean?
     
  4. dave

    Dave New Member

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


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK

    In Proteus... The basic resistor primitive model is called "RES" ...
     
  6. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
     
  7. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    actually I made post #1 just for learning c program
    actually I have cy8ckit -049-42xx Psoc 4 prototyping KIt (cortex m0). I only need c code. I did google search, I found all about LCD display. but I need code for LED. I am attaching two pictures

    pin 1, 2 connected with crystal
    pin 3 connected with 3.3 v battery
    pin 4 connected with ground
    p3.0 SCL connected with pin 5
    p3.1 SDA connected with pin 6
    pin 8 connected with vcc

    My task
    LED will turn on for 20 seconad
    LED will turn off for 1 houre
    LED will turn on for 10 minute
    LED will turn off for 1 hours

    here I just need to place c code
    Code (text):
    */
    #include <project.h>

    int main()
    {
        /* Place your initialization/startup code here (e.g. MyInst_Start()) */

        /* CyGlobalIntEnable; */ /* Uncomment this line to enable global interrupts. */
        for(;;)
        {
            /* Place your application code here. */
        }
    }

    /* [] END OF FILE */
     
    how to write c program for minute , hours , day and months ?
     

    Attached Files:

  8. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    I just create an array called TIME

    unsigned char TIME[7];

    Then I use the I2C to load the array every cycle. I created two functions to Write to the RTC and Read the RTC
    Code (c):

    */
    #include <project.h>
    #include "i2c.h"

    unsigned char TIME[7];

    void Readtime(unsigned char* array)
       {
        unsigned int idx, tmp;
       for(idx=0;idx<7;idx++)
          {
          tmp = RtcRead(idx );                   // read RTC
          array[idx] = tmp>>4 *10 + tmp;   // convert to decimal...
          }
       }
    void main(void)  //<--- always a void in embedded systems
      {
        while(1)
          {
          Readtime(&TIME[0]);    // Reads the time... &TIME[0] is the address of the array
          }
      }

    /*END OF FILE */
     
     
    Once you have the array
    TIME[0] = Seconds
    TIME[1] = Minutes
    TIME[2] = Hours
    TIME[3] = Weekday
    TIME[4] = Day
    TIME[5] = Month
    TIME[6] = Year
    TIME[7] = Control

    bit 7 of seconds is the on / off
    bit 6/7 of the hours is the AM / PM

    Control has the square ware output settings ( you can use this as the 1 second interrupt.)
     
    • Like Like x 1
  9. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    Please tell in simple steps for working with DS1307
     
  10. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    While i was searching code, what is this
    I2C1_Wr(0xD0);
    0xD0 mean?
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    The Ds1307 has the address of 0xD0... Everything on an I2C bus has an address... EEproms are usually 0xA0
     
  12. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hello,
    In whole data sheet i can't find this addr 0xD0?
     
  13. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    hello ,

    I saw following code. I am trying to understand.
    Code (text):
    sbit SCL=P3.5;
    sbit SDA=P3.1;
    void start();
    void wirte(unsigned char);
    delay(unsigned char);

    void main()
    {

    start();
    write(0xA2); //slave address//
    write(0x00); //control register address//
    write(0x00); //control register 1 value//
    write(0x00); //control regiter2 vlaue//
    write (0x28); //sec value//
    write(0x50) ;//minute value//
    write(0x02);//hours value//
    }

    void start()
    {

    SDA=1; //processing the data//
    SCL=1; //clock is high//
    delay(100);
    SDA=0; //sent the data//
    delay(100);
    SCL=0; //clock signal is low//
    }
    void write(unsigned char d)
    {

    unsigned char k, j=0×80;
    for(k=0;k<8;k++)
    {
    SDA=(d&j);
    J=j>>1;
    SCL=1;
    delay(4);
    SCL=0;
    }
    SDA=1;
    SCL=1;
    delay(2);
    c=SDA;
    delay(2);
    SCL=0;
    }
    void delay(int p)
    {
    unsignedinta,b;
    For(a=0;a<255;a++); //delay function//
    For(b=0;b<p;b++);
    }


     
     
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    That is a bad example to follow.... The write function is including the nack and disregarding the stop!!
     
  15. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5

    Attached Files:

  16. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    hello Ian
    please look at following code. there is time array. but I don't understand how does time array used in code
    Code (text):

    */
    #include <project.h>
    #include <stdio.h>

    #include "DS1307.h"

    #define ADDR 0x68

    #define SET_TIME 1


    uint8 wrBuff[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    int main()
    {
        uint32 rdStatus = 0;
        uint32 wrStatus = 0;
        uint32 nTime = 0;
        uint8 rdBuff[16];

        CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
       
        LCD_Start();
        LCD_PrintString("Hello");
        I2CM_Start();
       
       
    //    SetTimeArray(&wrBuff[1], 0x00104500, 0x02131209, (DS1307_ST_12HR|DS1307_ST_PM|DS1307_ST_SQOUT_1HZ) );
       
        SetTimeArray(&wrBuff[1], 0x00054000, 0x01131215, (DS1307_ST_12HR|DS1307_ST_PM|DS1307_ST_SQOUT_1HZ) );

        CyDelay(200);

        // Set time function, uncomment to set time.
    //    wrStatus = I2CM_I2CMasterWriteBuf(ADDR, wrBuff, 9, I2CM_I2C_MODE_COMPLETE_XFER);
        CyDelay(20);
    ;
       
        for(;;)
        {
           
       
            I2CM_I2CMasterClearStatus();
            wrStatus = I2CM_I2CMasterWriteBuf(ADDR, wrBuff, 1, I2CM_I2C_MODE_COMPLETE_XFER);
            CyDelay(20);
            wrStatus = I2CM_I2CMasterStatus();

           
            I2CM_I2CMasterClearStatus();
            rdStatus = I2CM_I2CMasterReadBuf(ADDR, rdBuff, 8, I2CM_I2C_MODE_COMPLETE_XFER);
            CyDelay(20);
            rdStatus = I2CM_I2CMasterStatus();

            LCD_Position(0,0);
            LCD_PrintString(GetTimeString(rdBuff, (DS1307_TIMEDATE2|DS1307_AMPM)));
           
            LCD_Position(1,0);
            LCD_PrintString(GetTimeString(rdBuff, DS1307_MDY));
           
            nTime = GetSeconds(rdBuff);
            LCD_Position(1,9);
            LCD_PrintInt16((uint16)(nTime >> 8) );
            LCD_Position(1,13);
            LCD_PrintInt8((uint8)(nTime & 0x00FF));

            CyDelay(500);
            /* Place your application code here. */
        }
    }



    /* [] END OF FILE */
     
     
  17. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    This function takes the whole array as a pointer &wrBuff[1] then the next two parameters contain BCD information to fill the array.. The final parameter is for the Square wave ouptut control and 24 /12pm parameters

    The function is more like C++ style programming.. The two BCD longs look like the set time 00:05:40:00 /13/12/15
     
  18. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    as you said about time array I created time array

    time array
    RTC_WriteAlarmSecond(5u);
    RTC_WriteAlarmMinute(3u);
    RTC_WriteAlarmHour(1u);
    RTC_WriteAlarmDayOfMonth(1u);

    void I2C_Init(void);

    // Set the minute as 55 (BCD format)

    SetTime.Minutes = 0x55;
    SetTime.Hours = 0x64;

    I don't understand how to use array in program ?
     
  19. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    You don't have to use an array... It just makes the job easier..

    The first 8 registers of the DS1307 are the time registers.... I transfer all 8 registers in one read ( for speed ) I can then manipulate and display their contents..

    I also like to work in decimal not BCD, so I convert the data to decimal for reading and then convert back to BCD to writing...

    Look at these statements

    Code (c):

    unsigned char PrinBuf[17];
    unsigned char TIME[7];
    while(1)
        {
        ReadTime(&TIME[0]);         // also does BCD conversion

        sprintf(PrintBuf,"%02d:%02d %02d/%02d/20%02d", TIME[2],TIME[1],TIME[4],TIME[5],TIME[6]);
        LcdOut(PrintBuf);
        }

     
    This makes keeping track effortless
     
  20. Parth86

    Parth86 Member

    Joined:
    Dec 25, 2011
    Messages:
    546
    Likes:
    5
    I am not using LCD .
    I am repeating again , what I want to do with ds1307 using LED

    Operation

    Set alarm for 5 second (automatically turn on LED for 5 second )
    Set alarm for 3 minute (automatically turn on LED for 3 minute)
    Set alarm for 1 hours (automatically turn on Led for 1 hours )

    SCL connected with P3.5;
    SDA connected with P3.1;
    LED connected with P1.6

    LED will read the data form ds1307 via i2c pins

    Code (text):
    #include <project.h>
    #include "i2c.h"
    sbit SCL=P3.5;
    sbit SDA=P3.1;
    sbit LED=P1.6
    void main()
    {

    RTC_ReadTime()
    RTC_ReadTime(0x00)   //  address value of seconds  register
    RTC_ReadTime(0x01)   //  address value of mintues  register
    RTC_ReadTime(0x02)   //  address value of hours  register address


    RTC_WriteTime()         // set alarm for specific time
    RTC_WriteAlarmSecond(5u); // set alarm for 5 second
    RTC_WriteAlarmMinute(3u);  // set alarm for 3 minute
    RTC_WriteAlarmHour(1u);    // set alaram for 1 hours


    RTC_WriteAlarmSecond()  // set alaram for second
    {
    SDA=1; //processing the data//
    SCL=1; //clock is high//
    delay(5);
    SDA=0; //sent the data//
    SCL=0; //clock signal is low//
    }

    RTC_WriteAlarmMinute()

    {
    SDA=1; //processing the data//
    SCL=1; //clock is high//
    delay(3);
    SDA=0; //sent the data//
    SCL=0; //clock signal is low//
    }


    RTC_WriteAlarmHour()

    {
    SDA=1; //processing the data//
    SCL=1; //clock is high//
    delay(1);
    SDA=0; //sent the data//

    SCL=0; //clock signal is low//
    }


    }
     
    [/QUOTE]
     
  21. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    Your code is not correct... The write to the I2C bus is a specific sequence..

    If you want to write to the device you have to:

    setup a start condition ( if bus is ready )
    write device address ( wait for ack )
    write register address ( wait for ack )
    write device data ( wait for ack )
    send nack ( to stop device )
    send stop ( to free bus )


    If you want to read from the device you have to:

    setup a start condition ( if bus is ready )
    write device address ( wait for ack )
    write register address ( wait for ack )
    send re-start( wait for ack )
    read device ( send ack if more data needed )
    send nack ( to stop device )
    send stop ( to free bus )

    Without this the device won't respond....
     

Share This Page