Continue to Site

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.

  • 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.

Clock

Status
Not open for further replies.
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.
 

Attachments

  • GEDC0009.jpg
    GEDC0009.jpg
    545.6 KB · Views: 170
Last edited:
premkumar9: I have used some other clocks but never the DS1307 ill check the datasheet and see what you are refering to.

But can you please explain it better.

EDIT
It sounds like you have a OSC issue. Are you sure the Crystal is good?

It is solved. First I confirmed oscillation and then a small error in code corrected.
 
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:
/*****************************************
    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:
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:
The DS1306 can be run in either 12-hour or 24-hour mode. Bit 6 of the hours register is defined as the
12- or 24-hour mode select bit. When high, the 12-hour mode is selected. In the 12-hour mode, bit 5 is the
AM/PM bit with logic-high being PM. In the 24-hour mode, bit 5 is the second 10-hour bit (20 to 23
hours).
 
Thanks Jason,

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



Code:
/*****************************************
    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;     
}
 
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
 
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 ?
 
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:
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:
1 more example would be i can replace all this code
Code:
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:
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!!!!
 
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:
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:
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;
}
 
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?
 
This snippet was used with DS1306.

I've some DS1305 at home, do you think it should be compatible with your DS1306 code ?
 
did some looking around datasheets and yep you can use it...

ds-jpg.49381


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
 

Attachments

  • ds.jpg
    ds.jpg
    92 KB · Views: 373
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top