The Beeb Body Building Course Part 12

Never forget an important date again! Build a real time clock for your BBC Micro.

Volume 1

Number 12

February 1984

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.