It's high time you had a real time clock
Not to mention a calander
Trouble with the BBC Micro's built-in timepiece is that it has
such a shocking memory...
MIKE COOK joins the Time Lords
THE pots were flying in the Cook household. I had committed
the heinous crime of forgetting a birthday. The accusation was
hurled, "You spend so long staring at that micro, it's a
pity it couldn't remind you".
"There's a thought", I mused, and this caused a temporary
loss of concentration which allowed a cold wet dish cloth to strike
me on the back of the neck.
The BBC Micro already has a real time clock built into it. The
only trouble is that every time the computer is switched off,
it forgets what time it is.
Also a time given in hundredths of a second is not very user-friendly.
What is needed is a clock that never stops and that can remember
the date as well.
So I set to it, designing a real time clock/calendar add-on
board for the user port.
There are several real time clock ICs on the market, all of
them are designed to be connected to the bus structure of a microprocessor,
so what I needed was one that could be tricked into thinking that
the user port of the BBC Micro was a microprocessor bus.
National Semiconductor's MM58174A was the prime candidate, so
the design was based on this chip. Figure I shows the pin-out
of this IC.
Figure I:
Pinout of the MM58174A real time clock
You will see there are four data lines (D0-D3) which are used
to read and write data to the chip. Also, there are four address
lines (A0-A3) which are used to specify which register in the
chip to read and write to. _
In addition there is a read line (RD), a write line (WR) and
a chip enable (CE). The chip enable is an input that turns the
device on so that it is ready for data transfer.
The bar over the top of the name indicates that a logic zero
is required in order for the line name to be true.
For example, the chip is only enabled when the CE line is at
logic zero. When this line is a logic one the chip is not enabled.
This useful convention is very widely used and informs you instantly
what polarity of signal is needed.
The other lines of this device supply it with power, signal
an interrupt and enable the quartz crystal to be added to provide
the time reference.
On the user port we have only eight data input/output lines,
and even by pressing control line 2 into service as an output
we are still short of one output.
The answer is to multiplex the address and data information
through the same four lines, leaving four lines for the control
lines.
This requires the address information to be written to a latch
just before we access the real time clock IC.
The full circuit is shown in Figure II. IC2 is the real time
clock IC. It is powered from the computer when it is turned on,
and by a Nicad battery when it is not.
Figure II: The real time clock circuit
Diode D1 prevents this battery from trying to power the whole
computer when it is switched off. Remember, current can only flow
one way through a diode. When the computer is turned on, the battery
is trickle-charged through resistor Rl which limits the current
to about 1mA.
Diode D2 provides a low resistance path when the battery is
powering the clock. The quartz crystal is attached to pins 14
and 15, and a small trimmer (variable capacitor) provides fine
adjustment of the time keeping.
The data input/output connections are taken to the least significant
four bits of the user port. These lines are also taken to IC1,
a four-bit latch.
A latch is a circuit which takes a snapshot of the logic levels
on its input and preserves them on its output. The event which
triggers the snapshot for this IC is the rising edge of the clock
signal (pin 9).
So, whenever this line makes the transistion from a logic zero
to a logic one, whatever is on the latch's four inputs is frozen
and transferred to its four outputs.
As these outputs are connected to the address lines of the real
time clock IC, we talk of "clocking the address into the
latch".
The only remaining function required is to set the read, write
and chip select lines to their appropriate levels. This could
be done directly by using the four remaining lines.
However, there would be a possibility that these lines might,
owing to other software running, get themselves into a state where
the real time clock was being told to read and write at the same
time.
This is obviously a chip-destroying combination and so IC3 is
used to make sure this can never happen.
This IC is a decimal decoder: when any decimal number is applied
(in binary form) to its inputs, the corresponding output goes
low.
For example, suppose the combination 0110 were applied to the
inputs, then output number six would have a logic zero on it and
all the other outputs would have a logic one on them.
Thus this IC ensures there is never a Read signal and a Write
signal present at the same time. The cost of this protection is
very small and so I thought it worthwhile to incorporate it.
The chip enable is connected directly to bit 7, and not through
IC3, as it needs to be held low at the same time as a Read or
Write signal.
The transistor in this signal path is to isolate the real time
clock from the computer's user port.
If this were not included then, when the computer was switched
off, this line would present a low impedance to earth effectively
enabling the real time clock chip.
But as the power is off, this chip is being supplied by the
battery at a reduced voltage, which is known as the "power
down" mode.
In this mode you cannot read or write to the chip. With the
chip enable connected to earth (low) in this mode, the time is
remembered but not updated.
I must confess I only found this out when I made the first prototype,
as the data sheets made no reference to the problem. It took several
hours of head scratching to work out why the time was the same
after switching on as it was on powering down.
At one stage I was going to incorporate this as a feature. Have
you noticed that most "features" are really design errors?
This project could then have been entitled "An elapsed
time indicator", measuring how long the computer had been
switched on to give an indication of when maintenance was due.
Also, when the board was disconnected from the computer it proceeded
to update the time normally, so it was ideal as a rental meter
as well. Those of you who want this "feature" should
just leave out the transistor.
The two resistors in the base circuit of the transistor are
to stop the same effect occurring when the computer is switched
off but the disc drives are turned on.
When this happens, about one volt is present on this user port
line which would be sufficient to turn the transistor on if it
were not for R2 and R3 (I didn't know about that either before
this project).
The real time clock IC is capable of generating an interrupt
signal, so this is connected to control line one.
All the components plus a printed circuit board are available
in Body Build Pack No. 9. (See Page 122.)
To connect this to the computer you need a ribbon cable with
two IDC (Insulation Displacement Cable) sockets which are available
as Body Build Pack No. 2.
Details about connecting the cable to the sockets were given
in the July 1983 issue of The Micro User. Pack No. 9 simply requires
soldering up, remembering to place the ICs and diodes the right
way round.
The component reference numbers are printed on the board, so
you can't really go wrong.
Like all hardware add-ons this requires software to drive it.
I have written a number of machine code routines that may be incorporated
into any program.
Also there is a routine that will display the date and time
in the top left hand corner of the screen whatever mode you are
using. This is driven by interrupts and can be left running while
another Basic program is running.
I have assembled these routines to sit in the RS432 buffer as
I seldom use this feature. However they may be placed anywhere
in memory.
The full program also incorporates a routine to enable you to
set up the clock with the correct time. Once set, it need never
be altered again.
However, having said that, my wife complained that during development
of this project I kept getting up in the middle of the night to
check it was keeping good time. That's my story and I am sticking
to it!
Table I shows the internal register locations of the real time
clock chip. Note that some locations are Read Only, some are Write
Only but most are Read/Write.
|
Register
|
Contents
|
Read orWrite
|
PageZero
|
|
0
|
Test mode/run
|
W
|
-
|
|
1
|
Tenths of seconds
|
R
|
&70
|
|
2
|
Units of seconds
|
R
|
&71
|
|
3
|
Tens of seconds
|
R
|
&72
|
|
4
|
Units of mins
|
R/W
|
&73
|
|
5
|
Tens of mins
|
R/W
|
&74
|
|
6
|
Units of hours
|
R/W
|
&75
|
|
7
|
Tens of hours
|
R/W
|
&76
|
|
8
|
Units of days
|
R/W
|
&77
|
|
9
|
Tens of days
|
R/W
|
&78
|
|
10
|
Day of week
|
R/W
|
&79
|
|
11
|
Units of months
|
R/W
|
&7A
|
|
12
|
Tens of months
|
R/W
|
&7B
|
|
13
|
Years
|
W
|
|
|
14
|
Stop/start
|
W
|
|
|
15
|
Interrupt
|
R/W
|
|
Table I: The real time clock internal registers
These locations contain the time and date as well as controlling
the operation of the clock. Most of these registers are self-explanatory,
but a few might need a little clarification.
Register 0 will place the chip into a test mode. This will feed
clock pulses to
various stages of the internal counters much faster than is
normal. Thus you do not have to wait four years to test if it
adds an extra day to February in leap years.
In this application we do not require this, and so for normal
operation a zero must be written in bit 3 in this register. The
years register is a Write Only register. It is used to count down
the years until a leap year comes along. The Interrupt register
is used to set the frequency while the real time clock IC generates
an interrupt. Table II summarises these registers.
Essentially, the computer has to generate a sequence of pulses
to access these locations. The program is shown in the listing
and, as it contains rather a lot of machine code it will need
a little more explanation than most. DO NOT PANIC (please note
the large friendly letters).
The machine code portion is written as a series of subroutines
and the operation is best understood by looking at these separately.
As mentioned before, the address and data information sent to
the real time clock chip are passed over the same lines, so we
need a subroutine that will select an address.
Lines 300-420 contain a subroutine to do just this: it is called
REGSEL, short for Register Select.
The address to be latched is first salted away on the stack
for use later, and lines 320 and 330 make all the user port lines
outputs. Then the address is recovered from the stack (340) and
the four most significant bits are cleared (350).
Bit 4 is set to one (360) and sent to the user port. Then bit
4 is cleared (380) and sent to the user port.
The effect of this is to give the latch a pulse and so store
the address information. As, after selecting an address we wish
to read or write to it, lines 510 and 520 enable the chip.
Figure III shows the sequence of events required to write to
an IC location. This is typical of the timing diagram for many
microprocessor components, so it will be quite educational if
you can follow what is happening.
Figure III:
Write cycle waveforms
Figure IV:
Read cycle waveforms
The subroutine to write to a register is contained in lines 430-530.
The location is assumed to be in the accumulator and the value
to be written is in the X index register.
The subroutine first calls the register-select subroutine which
we first looked at. Then it transfers the value to be written
into the accumulator and cleans it up (450, 460).
Bits 6 and 7 are set (470) to enable the chip and activate the
write line. The write line is then de-activated (490) and finally
the chip is disabled.
Using this subroutine, we can write to any IC location in the
real time clock.
Most of the time however, we wish to read the time from the
clock. The subroutine JUST1 (200-290) will read just one location
in the IC.
This subroutine assumes the address has been selected and the
chip enabled by the REGSEL routine before it is entered.
It first makes the four least significant bits of the user port
into inputs (200, 210) and then activates the read line on the
IC (220).
It then gets the data (240) and stores it into the Y index register
(260). It then "cleans up" the signals by de-activating
the read line and disabling the IC.
In order to read all the time and date values, subroutine REGREAD
(100-190) transfers all the relevant registers into page zero
memory.
The memory may then be examined by use of the indirection instructions.
This is useful if you require any part of the time or date in
numeric form.
Table I shows the page zero locations where each register is
stored. For most applications, the date will be most useful in
the form of a string. This is stored starting at a memory location
represented by the variable DATE.
Thus it can be accessed by the string indirection operator.
For example the command:
PRINT $DATE
will print the string containing the date.
This string is updated by calling the UPDATE subroutine in lines
770-940. This takes the values stored in page zero and converts
them into Ascii values (900).
They are then stored in the string previously set up in lines
1410-1430. For simplicity, this only updates the time and not
the day and date. So if you are burning the midnight oil you could
be misled.
The subroutine DISTIME is used to display this string in the
top left-hand corner of the display.
Using the operating system call, it first gets the current position
of the cursor and stores it on the stack (540-600). Then the cursor
is moved to the top of the screen (610) and the string is printed
(620-690).
The cursor is then restored to its original position (700-760).
The printing routine used will go directly to the screen and will
not be directed to the printer if it is switched on.
All the previous routines can be called explicitly from your
program, but it is possible to make the real time clock IC generate
an interrupt at intervals and use this to automatically display
the time and date.
This should be used with caution, as some of the machine-operating
system calls made are not fully re-entrant.
This means that, if the interrupt occurs while the computer
is executing one of these routines and the interrupt routine calls
the same routine, the computer will get its under-garments in
a twist.
The only time I have seen this happening is when trying to edit
a line with the real time clock display on.
The subroutine IRQSR (interrupt request service routine) will
handle all the interceptions of any interrupt generated, and take
the appropriate action if it is the real time clock causing it.
The main task of dealing with the real time clock is handled
in the subroutine START.
The interrupt is first cleared by writing a zero to the real
time clock's interrrupt register and then by reading it three
times. (Don't ask me why, it just says that in the data sheet.)
The display is updated (1150) and the interrupt timer is set
to generate another interrupt in half a second.
The real time clock is capable of timing to a tenth of a second.
But I have not included this in the display as I am only updating
the display every half a second.
It is possible to get the real time clock to interrupt at other
time intervals by writing a different number to register 15, See
Table II.
|
YEAR REGISTER
|
|
Value
|
Meaning
|
|
8
|
Leap year
|
|
4
|
Leap year + 1
|
|
2
|
Leap year + 2
|
|
1
|
Leap year + 3
|
|
INTERRUPT REGISTER
|
|
Value
|
Meaning
|
|
0
|
No interrupts
|
|
1
|
Interrupt after 0.5 second
|
|
9
|
Interrupt every 0.5 second
|
|
2
|
Interrupt after 5.0 seconds
|
|
10
|
Interrupt every 5.0 seconds
|
|
4
|
Interrupt after 60 seconds
|
|
12
|
Interrupt every 60 seconds
|
|
START/STOP
|
|
Value
|
Meaning
|
|
0
|
Stop
|
|
1
|
Start
|
|
TEST MODE
|
|
Value
|
Meaning
|
|
0
|
Normal running
|
|
8
|
Test mode
|
Table II: Special registers in the real time clock
The rest of the program initialises memory locations needed by
these machine code routines and programs two function keys to
start and stop the automatic display.
Note that the call address is given in hex rather than as a
variable name. This allows the program to be deleted and a new
one run, and the keys will still work.
The procedure at the end of the program allows the initial setting
of the clock (1560-2090). This need only be entered once as the
time should be maintained after that.
However, when crossing international date lines and coping with
the clocks going forwards and backwards it will need to be used.
The year is needed to see if it is a leap year, but it cannot
be read.
This program must be run once on power-up to initialise the
computer. This could easily be called from a !BOOT file for those
of you with discs.
If you have tape, remember it will only be necessary to run
this program if you want to use the real time clock. If not, then
just leave it attached, as the computer will be charging up its
batteries.
A fine adjustment may be made on the time keeping properties
of this board by use of the small trimmer. If the trimmer is closed
up (more of the two plates overlapping) then the clock will run
slower, opened up it will run faster.
This adjustment is very fine and the effects will only be noticed
over several days.
Having built the basic board and written the driving software,
it can now be incorporated into your own programs.
Imagine a program that scans a data base and tells you of any
birthdays in the coming week, or one that works out the number
of shopping days to Christmas. (Not another one already-Ed.)
How about the ultimate in desk diaries that will store your
appointments and remind you when to put your best suit on?
The computer could even be programmed to give you cheery little
messages if powered up on your birthday or on holidays, or inform
you that you should be getting paid at double-time rate.
If you have a speech synthesiser fitted, you can have your very
own speaking clock! Write in and tell me what you will be using
it for and we will publish the best ideas and programs.
That's all for now, but watch out for something very different
in our first anniversary issue.
Body Build Pack No 9 consists of:
IC1 74LS175 Quad edge-triggered latch;
IC2 MM58174A Real-time clock;
IC3 74LS42 Decimal decoder;
D1 & D2 1N4148 diode;
C1 5pf to 65pf variable capacitor;
T1 BC182 transistor;
R1 & R2 1k resistor;
R3 & R4 3k9 resistor;
Xl 32.768kHz miniature watch crystal;
Bl 3.6v PCB mounting Ni-Cad battery;
20 Way IDC straight solder tail plug;
one printed circuit board;
three 16-pin IC sockets.
Note — you will also need Pack No 2 or similar.
• You can order this pack and previous ones with the order form
on Page 122.