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

Clock

Discussion in 'Microcontrollers' started by AtomSoft, Dec 24, 2008.

  1. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Yes he is :D

    Heh if the post is old and outdated then its not really important anyway. Thanks for the heads up tho. Ill use the Attachment option from now on.

    But since those pictures are not a major part of this topic i will not reupload them to the site. Instead i will leave the non critical pictures already on photobucket well... on photobucket and attach from now on.

    Thanks guys.
     
  2. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    Attached Files:

    Last edited: Feb 4, 2009
  3. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    It is clearer. The spec near the E and the chips show more definition.
     
  4. dave

    Dave New Member

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


     
  5. premkumar9

    premkumar9 Member

    Joined:
    Oct 28, 2008
    Messages:
    513
    Likes:
    1
    Location:
    India

    It is solved. First I confirmed oscillation and then a small error in code corrected.
     
  6. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    Hello,

    Jason, would you please post your last MPLAB package and Proteus simulation of your nice DS1306 RTC project ?


    May i have some questions :

    If i want to use 24H format instead of 12H , what should i change in BCD function ?

    what | 0x40 = 12 Hour Mode do exactly ?

    i do not understand it well, what should i modify if i want to go with 24H format ?


    Code (text):
    /*****************************************
        Convert to BCD for the RTC(DS1306)
    ******************************************/  

        bcdHour = uint2bcd(decHour) | 0x40;     //0x40 = 12 Hour Mode
        if(decAMPM >= 1)
            bcdHour = bcdHour | 0x20; //0b00100000

        bcdMin = uint2bcd(decMin);

    Best Regards,
     
    Last edited: Dec 24, 2010
  7. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    I dont have a proteus file sorry :(

    The | 0x40 simply sets the bit for 12hr mode... for the RTC

    Ok to use this with 24HR mode is hard because you have to edit a lot of code heh...

    Remove all the | 0x40... since this tells the RTC that we use 12hr mode...
    Now you have to remove all the AM and PM code...
    Then you have to find all the code that has to do with the HOUR only and have it also read the 5th bit of RTC ..

    From the datasheet:
     
  8. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    Thanks Jason,

    Can you post your latest MPLAB project in zip file please ?
     
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
  10. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    Thanks Jason,

    Can you explain me how BCD to DEC works, i do not understand what "type" is used for ?



    Code (text):
    /*****************************************
        Convert a Decimal To LCD
    *****************************************
        h = HIGH PART   -    l = LOW PART
    *****************************************
        Converts to BCD then Splits BCD
        returning HIGH/LOW in a char    
    ******************************************/  
    char dec2lcd(char type, char dec){
        char tmp;
        tmp = uint2bcd(dec);

        switch(type){
            case 'u':
                tmp = (tmp >> 4) + 0x30;        //High Nybble
                break;
            case 'l':
                tmp = (tmp & 0x0F) + 0x30;      //Low  Nybble
                break;
        }

        return tmp;    
    }
     
  11. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Since i didnt understand INT types back then i used that char TYPE ....

    What it does is selects between 'u' which is UPPER BYTE and 'l' LOWER BYTE

    Because you are changing a DECIMAL which in this can should be anywhere from 0 to 60(min or sec) or 0 to 12(hour)
    There are 2 bytes for the ASCII aka LCD data

    Lets say our decimal is 12...

    To display 12 on the LCD we have to make it into 2 bytes.
    the first byte is 1
    the second byte is 2

    To do this we convert the DECIMAL to BCD... Now BCD will have : 0001 0010 which is 12 in BCD

    (0x30 is ASCII value '0')

    Now we take the UPPER BYTE and add 0x30; so 0x30 + 1 = 0x31 which is ASCII for '1'
    Now we take the LOWER BYTE and add 0x30; so 0x30 + 2 = 0x32 which is ASCII for '2'

    Now when you send 0x31 to LCD it will show a 1 on the LCD and when you send 0x32 is shows a 2

    If you send the 0x31 then 0x32 it will show "12" on the LCD
     
  12. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    Should we simplify it with a int to char, something like itoa ?

    Then it should convert a int to an ASCII displayable on a LCD in one shot.

    In this case, if I understand well we should not add 0x30 to the result ?
     
  13. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    actually no... since if we use a int we have to add 0x3030 remember ASCII is not like DECIMAL or BCD...

    The actual NUMBER 0 we see everywhere even when we type it is ASCII code 0x30

    A Character LCD takes in ASCII data... so to display any number from 0-9 you have to send 0x30 to 0x39...
    ASCII = HEX
    0 = 0x30
    1 = 0x31
    2 = 0x32
    3 = 0x33
    4 = 0x34
    5 = 0x35
    6 = 0x36
    7 = 0x37
    8 = 0x38
    9 = 0x39

    So display x digits we have to send x bytes...
    Like the number 200 has to be spit into 3 bytes

    from the chart above thats
    0x32,0x30,0x30

    Sending those 3 bytes will show 200...

    But i recommend not even using that anymore. I use sprintf now.

    Lets say you have 2 numbers...
    Code (text):

    char StringBuffer[16];
    char Num1 = 10;
    char Num2 = 5;

    char Result = Num1 * Num2;

    sprintf(StringBuffer, "%i x %i = %i\0",Num1,Num2,Result);
    LCD_String(StringBuffer);
     
    That will display on the LCD = "10 x 5 = 50"
     
    Last edited: Dec 26, 2010
  14. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    1 more example would be i can replace all this code
    Code (text):

    void UpdateTime(void) {
        unsigned char tmp,tmp2;
        char i;

        // Fill In the LCD String
        time[0] = 'T';
        time[1] = 'i';
        time[2] = 'm';
        time[3] = 'e';
        time[4] = ':';
        time[5] = ' ';
        time[8] = ':';
        time[11] = ' ';
        time[13] = 'M';
        time[14] = ' ';
        time[15] = ' ';
                            sprintf(time,"Time: %i:%i %cM  ")
                            sprintf(comDate,"Date: %i/%i/%i ")
        // Get Date
        comDate[0] = 'D';
        comDate[1] = 'a';
        comDate[2] = 't';
        comDate[3] = 'e';
        comDate[4] = ':';
        comDate[5] = ' ';
        comDate[8] = '/';
        comDate[11] = '/';
        comDate[14] = ' ';
        comDate[15] = ' ';

       // Get Minutes
        tmp = RTCRegRead(0x01);
        time[10] = (tmp & 0x0F) + 0x30;
        time[9] = (tmp >> 4) + 0x30;
       
        // Get Hours
        tmp = RTCRegRead(0x02);
        time[7] = (tmp & 0x0F) + 0x30;
        time[6] = ((tmp >> 4) & 0x01 ) + 0x30;

        // GET AM or PM (already read register 0x02)
        time[12] = (tmp >> 4) & 0x02;

        if(time[12] == 0){
            time[12]='A';
        } else {
            time[12]='P';
        }

        //Get Month
        tmp = RTCRegRead(0x05);    
        comDate[6] = (tmp >> 4) + 0x30 ;
        comDate[7] = (tmp & 0x0F) + 0x30 ;

        //Get Date(day)
        tmp = RTCRegRead(0x04);    
        comDate[9] = (tmp >> 4) + 0x30 ;
        comDate[10] = (tmp & 0x0F) + 0x30 ;


        //Get Year
        tmp = RTCRegRead(0x06);    
        comDate[12] = (tmp >> 4) + 0x30 ;
        comDate[13] = (tmp & 0x0F) + 0x30 ;

        lcd_line(2);
        lcd_string(time);

        lcd_line(1);
        if(view == 0){
            lcd_string(company);
        } else {
            lcd_string(comDate);
        }

        decMonth = bcd2dec(RTCRegRead(0x05), 2);
        decDate  = bcd2dec(RTCRegRead(0x04), 0);
        decYear  = bcd2dec(RTCRegRead(0x06), 0);

        decHour  = bcd2dec(RTCRegRead(0x02),1);
        decMin   = bcd2dec(RTCRegRead(0x01),3);
        decAPM   = bcd2dec(RTCRegRead(0x05),0);
        decAPM   = (decAPM >> 5) & 0x01;
    }
     

    With this new code

    Code (text):

    void UpdateTime(void)
    {
        int hours,minutes,aorp;    //aorp = Am or Pm
        int month,date,year;


        minutes = bcd2dec(RTCRegRead(0x01),3);
        hours = bcd2dec(RTCRegRead(0x02),1);
        aorp = bcd2dec(RTCRegRead(0x05),0);
        aorp = (aorp >> 5) & 0x01;
        if(aorp == 0)
            aorp ='A';
        else
            aorp ='P';
       
        month = bcd2dec(RTCRegRead(0x05), 2);
        day = bcd2dec(RTCRegRead(0x04), 0);
        year = bcd2dec(RTCRegRead(0x06), 0);

        sprintf(time,"Time: %i:%i %cM  ",hours,minutes,aorp)
        sprintf(comDate,"Date: %i/%i/%i ",month,day,year)
    }
     
    !!!UNTESTED!!!!
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    I think i can rewrite that whole thing and the code lines would be about half the size now
     
  16. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    Thanks, I see better now.

    There is also something I don't understand well with SPI and RTC:
    When reading the time, we set the read register and then we send 8 times 0x00 to fill in the buffer.

    But why send 8 times 0x00, normally sending one time the read register address should get the result, shouldn't it ?
     
    Last edited: Dec 26, 2010
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Where do you see that at?
     
  18. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    you are right i did not see that in your code.

    I found a code somewhere that do the following to fill-in a table with value, what do you think about it ?

    I do not understand why it uses dummy read with 0x00 :


    Code (text):
    void RTC_read2table(char address, unsigned char *table)
    {
        unsigned char p, i;
         
        RTC_CS_IO = 0;
        RTC_SPI_IF = 0;
        RTC_SSPBUF = address;                                // Send SPI address

              for(i=0;i<7;i++)                              // Send 8 times 0x00 and fill-in table with results.   
            {
             RTC_SSPBUF = 0x00;                            
             while (!RTC_SPI_IF);
             p = RTC_SSPBUF;
                    (table[i])=p;
            }
           
        RTC_SPI_IF = 0;
        RTC_CS_IO = 1;
    }
     
  19. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Wow that is very weird ... how is RTC mixed with SPI? wow!!

    It looks like if someone defined RTC_SSPBUF to be the SPI bus with the RTC which is kinda weird, better naming would have been RTC_DATA

    Its hard to say what it does without knowing what RTC they used.. i think they might be writing to internal RAM on the RTC some come with NVRAM which the user can use to hold data...
    I have no clue why thy are writing zeros tho... unless writting zeros is a read command or something. i have no clue heh

    Do you know which RTC they are using?
     
  20. crocu

    crocu Member

    Joined:
    Feb 20, 2009
    Messages:
    118
    Likes:
    1
    Location:
    France
    This snippet was used with DS1306.

    I've some DS1305 at home, do you think it should be compatible with your DS1306 code ?
     
  21. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    did some looking around datasheets and yep you can use it...

    [​IMG]

    Also that code you posted looks more like hes reading the RTC in burst mode ... hes sending 0x00 just for the clock to continue...

    It seems to be reading 7 bytes at a time
     

    Attached Files:

    • ds.jpg
      ds.jpg
      File size:
      92 KB
      Views:
      210
    Last edited: Dec 26, 2010

Share This Page