It's 13 O'clock!

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

Since the last ice age I have been trying to get my Nixie Clock (Atmega162) to talk to a DS1302 RTC.

Since I use Codevision, with a built-in library, I tried that first. It works, but I can't figure out how to get 12-hour mode.

So I stole some code from here:
http://www.nerdkits.com/library/...

made a few changes (just pin definitions etc), and it works! But again, its only 24-hour!

So I have been trying to figure out how to make it 12-hour...

Here in the initialization code, you can see where I have commented-out the 24-hr setting, and added a 12-hour setting.

I have commented each line, so you can see what I am trying to achieve -

-read 0x85 (read hours address)
-set bit 7 Hi (12-hour mode)
-write back to 0x84 (write hours address)

... and it totally doesn't work - still ticks over to 13:00:00

Can anybody see what I'm doing wrong?

Code snippet attached here, full code as attachments.

void rtc_init()
{
    unsigned char tmp; // temp variable
    unsigned char tmp2; // temp variable
    reset();
    send(0x8E); // tell ds1302 what we want to read/write
    send(0x00); // turn off write protect

    reset(); // read seconds then write them back. this gets the clock ticking
    send(0x81);
    tmp = read();
    reset();
    send(0x80);
    send(tmp);
    
    //------------added by me--------------
    
    reset();            // read hours and make sure mode is on 12 hour     BIT 7 SHOULD BE HI
    send(0x85);         // tell the DS1302 that we want to read 0x85 (hours)
    tmp = read();
    send(0x84);         // tell the DS1302 that we want to WRITE 0x84 (hours)
    tmp |= (1<<7);      //set bit 7 Hi   
    send(tmp);
 
    
    //------------removed by me--------------
    /*
    reset(); // read hours and make sure mode is on 24hour
    send(0x85);
    tmp = read();
    tmp2 = (tmp & (1<<7));
    if (tmp2)
    {
        reset();
        send(0x84);
        tmp &= ~(1<<7);
        send(tmp);
    }
    */

}

Thanks!
Pete

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are correct. The CV libraries do not seem to cater for setting a 12-hour clock. OTOH, who would ever want a 12-hour clock?

You need to set bit6 in the hours register of a DS1307. I guess that a DS1302 will be the same.
The problem is that the rtc_set_time() function takes binary arguments, not BCD arguments.

Just try setting the time to 48:41:30 BST.
The time is really 08:41:30 BST

I suppose that I could try it for myself on a DS1307.
Edit again. Yes. You can ADD in decimal values into the hours argument. e.g. hours + 40 to set 12-hour mode, hours + 40 + 20 to set PM in 12-hour mode. Remember to do your hours display without these extra bits showing. Which is a pain in binary, a cinch in BCD.

It is now 1:17:32PM BST. So I would use:

rtc_set_time(40 + 20 + 1, 17, 32);

How does a 12-hour clock work at midday?
Does it say 12.00 or 0.00PM ? Likewise, 12.00AM or 0.00AM ?

David.

Corrected my earlier OR with ADD decimal values. Of course OR only works with BCD.

Last Edited: Fri. Apr 13, 2012 - 11:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Does it say 12.00 or 0.00PM ? Likewise, 12.00AM or 0.00AM ?
12:xx am or pm until 1:00 am/pm. So easy even Aussie can use it. :lol:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can write any value to any address in the RTC (with CV) using

rtc_write (location, value);

I think I found that from another thread or browsing the rtc.h file - it doesn't appear to be in the CV manual IIRC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If hour > 12 then hour -= 12?

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

You can write any value to any address in the RTC (with CV) using

rtc_write (location, value);

I think I found that from another thread or browsing the rtc.h file - it doesn't appear to be in the CV manual IIRC


From CV Help, recent version:

Quote:
void ds1302_write(unsigned char addr, unsigned char data)

this function stores the byte data at address addr in the DS1302 registers or SRAM.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee,

You probably have a DS1302, and I do not.

If you choose to use the CV rtc_get_time() and rtc_set_time() library functions for 12-hour o/p, will my trick work?

It is not complicated to display. You just have to use non-BCD maths:

// set time
if (fmt_12hr) {
   hour += 40;
   if (PM) hour += 20;
}
rtc_set_time(hour, min, sec); 
...
// get time
rtc_get_time(&hour, &min, &sec);
if (fmt_12hr) {
    hour -= 40;
    if (hour >= 20) {
         hour -= 20;
         PM = true;
    }
}
// display with printf()

The rtc_write() function is possibly a less devious way of setting 12-hour format.
OTOH, you still have to display the values correctly.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MartinM57 wrote:
You can write any value to any address in the RTC (with CV) using

rtc_write (location, value);

I think I found that from another thread or browsing the rtc.h file - it doesn't appear to be in the CV manual IIRC

Ah...but I use a DS1307 (not DS1302 - doh!) and ds1307.h includes:

void rtc_write(unsigned char address,unsigned char data);

...but it's not in the 2.05.7 manual in section 4.22.4 (Maxim/Dallas Semiconductor DS1307 Real Time Clock Functions). So theusch, we're both correct :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
You are correct. The CV libraries do not seem to cater for setting a 12-hour clock. OTOH, who would ever want a 12-hour clock?

I know what you mean, I like 24hr clocks too, but this is for the end users, who will be normal 12-hour people!

I read the CVAVR documentation, but it appears that you can write to a register, but some other stuff I read implied that CVAVR keeps the ds1302 write-protected, so then I tried to figure out how to turn off the write protection etc...

I love CVAVR because of the libraries (LCD etc), but in this case too much is hidden/incomplete, and I can't see it to know what it's up to...

I was hoping that by using the other library that I might follow the code and understand a bit more of what is going on. It's well commented, and I learned a few things, but I'm still a bit stumped.

Quote:

It is now 1:17:32PM BST. So I would use:

rtc_set_time(40 | 20 | 1, 17, 32);

I tried this (using the non-CVAVR library)

write_hours(40 | 20 | h); 

As I press the hours+ button, the hours go :
20 - 21 - 22 - 23 - 20 and so on.

Is this actually setting the clock into the genuine 12-hour mode like the manufacturer intended, or is this using clever maths to make the 24-hr time appear like 12-hour?

Does it look like my edited code to set bit7 is actually working?

I originally just wrote my own code to try to detect when it was PM, and display the PM marker etc, but it was getting quite messy, and I felt like I was missing the point somewhat - the nice people at Maxim have built in a 12-hour mode, if I could just figure out how to get it!

Thanks again
Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no clever maths. These RTC chips are designed to work in BCD. Which they do very well.

If you read the DS1307 (or DS1302) registers, you get BCD. e.g. 0x59 minutes. Display with printf("%02x")

Punters do not like this. So the library functions do a bcd2bin() conversion when reading. And a bin2bcd() when writing. Just so you can use printf("%02d")

All that I was doing was creating the BCD digits in a binary number. e.g. setting the fmt_12hr bit.

Most third party libraries either ignore these 'features' or expect you to understand BCD like a regular adult.

If you want to understand any CodeVision library code, examine the LST file. I was idle. I just tried creating BCD digits, and seeing if it worked. e.g. set to 11:59:30PM and watch the RTC display change the date, and use the wierd 12.00.00AM format.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

Thanks for all the info.

I will spend the weekend (at least!) reading it over and over until it sinks in :-)

I have already got a few key points from your info:

When I thought I was reading the time from the registers, I was actually reading the time from-the-registers-and-tidied-up-for-humans.
I tried reading the registers directly and printing the hex, so now I have a better understanding of what is going on.

I'll keep at it - thanks!
Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oops. I have corrected my earlier post. You should do decimal maths with ADD and SUBTRACT.

BCD maths can use OR and AND.

Quote:
When I thought I was reading the time from the registers, I was actually reading the time from-the-registers-and-tidied-up-for-humans.

The Help files and example code uses ordinary numbers.

Good Luck.

David.