# Why do real-time clock chips use BCD

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.

-
I do not know the answer but I wonder if there is any correlation to BCD to 7-Segment Decoder's? – Prof. Meow Meow Apr 5 '11 at 17:11
@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. – supercat Apr 10 '11 at 16:58

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

-
If a chip has the ability to ignore certain bits in its alarm function, I suppose interrupts every ten seconds, sixty seconds, ten minutes, or hour might be nicer than at power-of-two increments, but "alarm = GET_RTC_SECONDS(); alarm -= (alarm % 360)-360; SET_ALARM_SECONDS(alarm); is hardly difficult. – supercat Apr 6 '11 at 0:27
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... – supercat Apr 6 '11 at 0:32
...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. – supercat Apr 6 '11 at 0:37
@supercat Try that with several alarm lengths (every 10 seconds + every minute). Basically RTCs are Real Time Clocks and not monotonic clocks you should base your RTOS timer on. How do you cope with setting the correct time with your RTC based alarms? You may find your system sleeping for a day or a year if the user set the wrong date, you set an alarm and later the user corrects the date. – jpc Apr 6 '11 at 2:01
@jpc: I do it with several alarm lengths pretty nicely; it would be better if the PIC's timers had compare registers that could operate in async mode, but fortunately there are two 16-bit timers that operate off the same 16Hz clock. Timer 1 free-runs, and I keep track of the last value I observe. For Timer 3, I compute how many 16ths of a second I should sleep, and if the answer is 2-240, I load a value 0xFF10 to 0xFFFE and make sure Timer 1 hasn't moved. If only 1/16 second remains, I busy-wait, since PIC timers will take 65,537 counts to signal overflow if loaded with 0xFFFF. – supercat Apr 6 '11 at 15:14

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.

-
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) – supercat Apr 5 '11 at 17:44
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. – supercat Apr 5 '11 at 17:53
@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 – Toybuilder Apr 6 '11 at 18:31
...it's much more likely that the time is not being kept by the program at all -- instead, anytime time is being used, just read/update the values on the RTC chip. – Toybuilder Apr 6 '11 at 18:32
@Toybuilder: In a battery-powered device, having the CPU service an interrupt hundreds or thousands of time per second when there's nothing useful to be done is a bad idea. It's much better to set a precise alarm to wake the CPU when needed. If an ARM chip had an RTC and a useful wakeup timer, both of which could run off the same 32KHz source, that'd be fine. I'd just fetch the RTC time once on startup, convert to seconds, and be done with it. None of the chips I've observed which can run the RTC off a separate battery from the CPU have a good wakeup facility, though. – supercat Apr 6 '11 at 19:53

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.

-
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! – supercat Apr 5 '11 at 18:20
@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. – Michael Kohne Apr 5 '11 at 20:08
I wonder what fraction of the people who use RTCC peripherals don't convert dates/times into Unix-style seconds counters? – supercat Apr 5 '11 at 22:58
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. – jpc Apr 5 '11 at 23:11
@supercat For daylight saving you are doomed since timezone databases are huge and change twice a year. Forget doing this on a really embedded system. The second operation you mention is easy with a second counter but then displaying the date is quite difficult. If it weren't you would not be complaining about the reverse operation. If you need to measure time periods -- use a timer and if you want dates -- use an RTC. What you did on your PIC is the best of both worlds (an RTC and a monotonic counter derived from the same reference). – jpc Apr 6 '11 at 2:08

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.

-
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... – supercat Apr 5 '11 at 22:50
...but the chips I've noticed which have a separately-powered RTCC use BCD YMDHMS. – supercat Apr 5 '11 at 22:51
The newer CPUs do this since it is cheaper and uses a little less current (especially important since the semiconductor process used is optimized for making CPUs and not RTCs). – jpc Apr 6 '11 at 14:47
@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? – supercat Apr 6 '11 at 15:43
I was thinking about @Toybuilders answer in which he stated that newer CPUs have only counters and not full-blown RPCs. – jpc Apr 6 '11 at 17:16

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.

-

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.

-
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. – supercat Apr 8 '11 at 22:24