14
\$\begingroup\$

I have seen dozens of different real-time clock chips on the market, as well as a number of processors with a built-in separately-powered real-time clock module.

Nearly all of them not only store time as year-month-day-hours-minutes-seconds, but even the individual fields are stored in BCD rather than binary format.

Is there some underlying reason for this?

Are there any microprocessor applications that do anything more sophisticated than simply display a clock where the BCD format is more useful than binary, or where year-month-day-hour-minutes-seconds format would be more useful than a straight 47-bit count of oscillator state changes?

From what I can tell, it seems RTCC makers add a lot of extra circuitry to make their chips less useful; the only reason I can figure for RTCC modules in processors to behave that way is that the processor vendors use some pre-existing BCD implementation rather than producing their own.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I do not know the answer but I wonder if there is any correlation to BCD to 7-Segment Decoder's? \$\endgroup\$ Apr 5, 2011 at 17:11
  • \$\begingroup\$ @Prof. Meow Meow: Nice name. The most practical method for storing numbers that are going to be displayed in hardware is BCD. There are systems that stored numbers to be displayed in other formats, but in many cases they simply used a ROM to map directly from the number to its visual representation (e.g. the arcade machine "Tank" used 6-bit score counters, and a 512 byte ROM to convert each score value to an 8x8 shape) but this was generally only workable if the maximum numerical value was fairly small. \$\endgroup\$
    – supercat
    Apr 10, 2011 at 16:58

6 Answers 6

13
\$\begingroup\$

Do all RTCs use BCD encoding?

RTCs from Philips/NXP (both standalone and integrated into ARM7 or Cortex-M3 chips) do not use BCD encoding.

What's wrong with a BCD RTC?

When compared to flat counter the only operations which are more difficult with a split BCD clock are time difference calculations (adding seconds or calculating elapsed time). Time comparisons like: "is current time greater than the alarm time set by the user" are just as easy.

What's nice about BCD (and generally split-field) RTCs?

Splitting the fields is really nice when you care for the calendar date. Human calendars have funny things like months of different lengths and on top of that leap years. Try to do that in a single counter (you can get a bonus point for using almost no power). Oh and try supporting week days (quite useful in all kinds of devices meant for humans: from alarm clocks to heater controllers) with this.

The BCD approach has one additional feature: you get "every second" or "every ten seconds" interrupts for free, without having to do any calculations on times or dates.

For the record leap year calculation is a little off in the NXP RTCs since it only cares for the divisible by 4 rule and does not check the division by 100 and 400. If it kept the year counter in BCD this would be trivial and most probably done right.

Summary

  1. If you want a monotonic clock then use one. You can buy a PIC or AVR with the "RTC counter" (which is just an asynchronous counter with an autonomous 32kHz oscillator). Just keep in mind that simply displaying the date will be difficult. :)

  2. When you need to display the time and date and set alarms based on user input of times and dates then use an RTC. And remember that when the user changes the current time and date your RTC based interrupts may be inaccurate.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ I've just started using the Gekko, which has a 24-bit RTC that's almost what I want except that it can't keep time when the processor's dead. I was also looking at an ST Micro ARM, which has a silly BCD RTC module which only supports interrupts on a one-second basis. If the ST chip would never be without power for more than three years, I could jinx the RTC prescalars to run at 32x speed, and then use software tricks to compensate, thus getting 1/32-sec time resolution on the wakeup events, but the times stored in the RTC would have no meaningful relation to calendar time and... \$\endgroup\$
    – supercat
    Apr 6, 2011 at 0:32
  • 1
    \$\begingroup\$ ...so the necessity of converting from the RTC's silly format to 1/32-second increments would be annoying, especially since such a conversion would be required on every sleep/wakeup cycle. I guess I'm curious how many people use RTCC readouts without converting into unified seconds. Maybe there are enough to make YMDHMS format worthwhile, but to my mind it's far more useful to reserve YMDHMS for human I/O, and use straight seconds (or whatever fraction thereof) for everything else. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 0:37
  • 1
    \$\begingroup\$ @jpc: My inclination would actually have been to never set the RTC-chip time, but instead keep "time since clock battery was installed", and store the difference between that and wall time. I used that approach in one generation of the product which used a separate PIC for keeping battery-backed time (the time on that PIC was read-only) and would use it on a chip with a straight counter. It seemed like a somewhat goofy idea, though, to have the machine's RTC store a meaninglessly-date-formatted value, though if I use the ST Micro chip I might just do that. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 15:23
  • 1
    \$\begingroup\$ BTW, the STM32F100 series uses a 32-bit seconds RTC (not BCD), but the STM32F400 series regresses back to a BCD encoded RTC. Sigh. \$\endgroup\$ Nov 27, 2012 at 21:43
  • 1
    \$\begingroup\$ @FedericoRusso: Split field would make some sense, though it's more apt to be a hindrance than a help in most applications. The choice of BCD, though, seems downright bizarre as a choice to bundle with a CPU that doesn't have any BCD support. \$\endgroup\$
    – supercat
    Sep 12, 2016 at 17:00
3
\$\begingroup\$

When using clocks in the end you're more likely to be interested in minutes and tens of seconds(towards displaying them) than just the total of seconds, minutes and so on. In case you're not interested in separate digits chances are that you don't care about separate minutes or seconds values either, and that you might as well use a long binary counter like you suggested.
It's easier to convert from BCD to binary in software than the other way around. And since BCD counters don't require that much extra real estate over binary counters it makes sense to choose for BCD.

\$\endgroup\$
9
  • 2
    \$\begingroup\$ How often does an application want to do nothing with a date and time other than display it? It seems to me that it's far more common to want to do things like compute a time some distance in the future, or determine how much time has elapsed since some particular event, etc. Which is easier to compute: the date and time 45 seconds after 28-Feb-2000 23:59:52, or 5097582+45 (the latter value assuming midnight 01-Jan-2000 as the epoch)? How about determining whether 5 minutes have elapsed between 28-Feb-2000 23:59 and 01-Mar-2000 00:03 (vs 5097540.0 and 5184180.0) \$\endgroup\$
    – supercat
    Apr 5, 2011 at 17:44
  • 1
    \$\begingroup\$ An RTC with a 48-bit counter for 65,536ths of a second and a alarm-compare module which covered the bottom 24 bits or so would be extremely handy for low-power systems since it could be used as the basis for OS scheduling independent of processor waking and sleeping. If something's supposed to happen 4 seconds from now, the system could note the RTC value when the event should occur. If 2 seconds from now the processor finds itself with nothing to do, it could set the RTC alarm and go to sleep. When the event should occur, the system would wake up. \$\endgroup\$
    – supercat
    Apr 5, 2011 at 17:53
  • \$\begingroup\$ @supercat - for general purpose computers, let the OS keeping track of time and do "useful things" with that time info. The RTC is only consulted once to initialize the OS's time info, and then time is updated by interrupts. But for many simple embedded use, it's much more likely that \$\endgroup\$
    – Toybuilder
    Apr 6, 2011 at 18:31
  • 1
    \$\begingroup\$ @Toybuilder: The latter is exactly the approach I ended up using in the last few generations of electronic lock. My biggest annoyances were the lack of any pulse output choices between 32Khz and 16Hz (since I didn't trust a 1M pullup to operate reliably with a 32Khz open-collector output, the only reasonable choice was 16Hz), and the sloppiness of the PIC's timer circuitry. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 20:43
  • 1
    \$\begingroup\$ @FedericoRusso: If one had a straight-binary time counter, one wouldn't have to convert back to hours, minutes, and seconds, except perhaps for human-readable display. One simply adds 3723 and that's it. When working with YMD-HMS date/time values, one needs separate code for incrementing and decrementing, daylight saving time is a nightmare for which chip makers seem to like to add broken support [like a command which subtracts one from the hour count except when it's zero, in which case it does nothing]. DST is a pain in binary too, but not quite as hideous. \$\endgroup\$
    – supercat
    Jan 17, 2013 at 2:44
3
\$\begingroup\$

I suspect several reasons:

Historical - they've been doing it this way for some time now. If you want your new part to replace some other part, then it has to more-or-less work the same. So you keep with the BCD.

Application - if someone is using an RTC from a small micro (something in the 8 bit range, like a low-end PIC), then dealing with a large number (such as your 47 bit counter) is a big pain in the neck. It's MUCH easier to deal with the BCD digits, as you don't have to work at breaking things up.

Not that hard - Doing the BCD counters isn't that hard, and in fact I think it isn't many more gates than doing them binary.

One can imagine a system where you get separate hour, minute, etc counters in binary instead of BCD (thus avoiding the 'breaking down the 47 bit number' issue), but it's not that much easier, and you're going to do some conversions when displaying the thing anyway.

\$\endgroup\$
12
  • 1
    \$\begingroup\$ The 48-bit number would be a 32-bit number of seconds and a 16-bit fraction. Working with 32-bit numbers on an 8-bit micro isn't that bad. I can imagine that on something like a 6502 which could handle packed BCD nicely, the BCD format might save a few bytes in some cases, though the added complexity of handling carry between seconds-hours-minutes would offset any advantage. But surely the people who built an RTCC into ST micro's ARM chips weren't expecting someone to use a 6502 to process the data--not with a 32-bit ARM sitting right there! \$\endgroup\$
    – supercat
    Apr 5, 2011 at 18:20
  • 1
    \$\begingroup\$ @supercat - while not hard, doing the 32 bit work on the 8 bit micro is still a pain in the <bleep>. And on something like a PIC (with VERY limited instruction & register & ram spaces) it's even more of a pain. As to the ARM chip - I'm going to bet that has more to do with historical precedent than anything else - everyone's used to doing it that way, so they keep doing it that way. \$\endgroup\$ Apr 5, 2011 at 20:08
  • 1
    \$\begingroup\$ I wonder what fraction of the people who use RTCC peripherals don't convert dates/times into Unix-style seconds counters? \$\endgroup\$
    – supercat
    Apr 5, 2011 at 22:58
  • 1
    \$\begingroup\$ supercat: All of them? Of what use are Unix-style timestamps in a clock? OTOH your only use case is RTOS alarms which are better served with a normal timer or with a simple "second increment" interrupt from the RTC. \$\endgroup\$
    – jpc
    Apr 5, 2011 at 23:11
  • 1
    \$\begingroup\$ @jpc: What if you want to determine whether a given date is in daylight saving time, or determine whether a program that starts on a certain date/time and lasts a certain length will overlap another one? Such things are easy with straight seconds, but harder with YMDHMS. As for using a normal timer, what I use at present is a 1/16-sec tick from an RTC chip driving TMR1 and TMR3 on a PIC; that gives me a 1/16-second-accurate wakeup that works even when the main CPU clock is stopped, and I derive all my timing from that. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 0:44
1
\$\begingroup\$

I agree with Michael Kohne that there's a lot of historical momentum.

Early MCU's also had much less space for code and data (think 128 BYTES of RAM, for example). Since time information is often used for human-interfacing purposes, it made more sense to keep the data closest to the format used to display to/input from humans.

Some newer MCU's with more code and data space sometimes implement hardware real time counters -- these devices often keep binary counts of 32kHz ticks.

\$\endgroup\$
21
  • 1
    \$\begingroup\$ I've coded for the Atari 2600 (128 bytes RAM), and I know the virtues of BCD. Things like scores are nearly always computed in BCD; level numbers sometimes are. Even on a 6502, though, I would expect that if I needed to determine whether two date/times were within five minutes of each other and determine whether daylight saving time was in effect, code to convert a 32-bit seconds counter into YMDHMS would be about as compact as code to do those computations without doing such conversions. As for newer CPUs, I've seen some with straight 32Khz counters that require the main CPU to be alive... \$\endgroup\$
    – supercat
    Apr 5, 2011 at 22:50
  • 1
    \$\begingroup\$ @jpc: Why is it cheaper and lower-current to use BCD YMDHMS? I would think a 47-bit read-only counter with a comparator on the bottom 32 bits would be simpler than all the date-parsing stuff in an RTC chip. Unless there's some master film of a BCD date circuit which, because of some arcane long-forgotten magic, can be plopped into a design to achieve lower currents than are available with modern methods, I'm not clear why BCD would be cheaper or use less current? \$\endgroup\$
    – supercat
    Apr 6, 2011 at 15:43
  • 1
    \$\begingroup\$ @jpc: The ones I've seen with counters, from what I've seen require that the main CPU be kept powered (which requires battery-backing the CPU and risking killing the battery if the CPU gets in a bad state while the main supply is off) and generally make it hard to keep continuous time across things like reboots or firmware updates. The only one's I've seen with separate battery-backup are YMDHMS-parsed BCD. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 18:02
  • 1
    \$\begingroup\$ @Toybuilder: I don't doubt that the process for making a dedicated RTC chip could yield a more power-efficient device than one for making a general-purpose CPU. On the other hand, I would think that on either type of chip, a straight counter would require no more current than a BCD YMDHMS one; I would also think that a 48 (or whatever) bit straight counter would require less current than the combination of a 24-bit straight counter and a BCD YMDHMS counter. \$\endgroup\$
    – supercat
    Apr 6, 2011 at 20:53
  • 1
    \$\begingroup\$ @Toybuilder: I can appreciate that there are advantages to standalone RTC chips. Who knows--maybe there's even one out there that's cheap and has a useful square-wave output that doesn't waste much current in a pullup resistor (e.g. a 256Hz output with a 1/65536sec low time would waste a small fraction of the current of a 16Hz output with a 1/32sec low time, despite offering a 256-fold improvement in resolution). \$\endgroup\$
    – supercat
    Apr 6, 2011 at 23:35
1
\$\begingroup\$

In case anyone is interested, I just looking at ST's 32F series and it seems that while the newer 32L series uses a BCD RTC, the 32F uses a straight 32-bit counter with configurable prescalar and provides a separate battery input for it (hooray!). I would have rather had a longer straight counter without a configurable prescalar (so I could get 1/256sec accuracy but keep time for years without having to worry about wrapping) but if I were to set the prescale for 1/64sec the timer could run two years without overflowing. Not ideal, but not too bad. A little unaesthetic that if someone powers the machine on after it's been off for too long (2.1+ years), the time/date would undetectably slip back by 2.1 years, but hardly a major problem (the counter has an overflow flag, but in many cases that wouldn't be terribly helpful. If the machine was on for two years prior to being powered off, and was powered on three months later, the timer would be expected to overflow; the question would be whether it had overflowed twice, and I don't know of any flag for that.

\$\endgroup\$
0
\$\begingroup\$

Maxim seems to be doing just what you want with DS1372U. It needs less than 1μA, costs 1.7 USD and is available(!) on DigiKey and Mouser. The only problem is that it does not seem to offer alarms with more than 1 second precision and the lowest output clock rate is $\approx$4kHz.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ It's a little pricey, and it doesn't allow any way to read out increments smaller than a second. A 4096Hz output would be nice, though it would be far nicer if it were low for 1/65536 of a second and high for 15/65536. Open-collector outputs should be low as little as possible. \$\endgroup\$
    – supercat
    Apr 8, 2011 at 22:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.