As the hardware is based on the existing standard PCB
additional four keys are simply attached to the six-pin
Power supply for that all comes either from three 1.5 V
batteries or from four rechargeable batteries of 1.2 V.
That allows to work with a 5 V standard LCD.
2 Software structure
The software can be programmed in two versions:
a 10 ms version: Time measurements are based on
a 10 ms cycle, with the time in four registers,
a 1 ms version: Measurement in a 1 ms cycle,
with the centiseconds in one register (from 0 to 99) and
the milliseconds (from 0 to 9) in an additional register.
The version described here is the second version with
milliseconds, even though the resolution of 1 ms is
a little bit inappropriate, given the large inaccuracy of
the internal RC oscillator.
The following properties determine the software design:
Clocking: setting of the internal clock prescaler
CLKPR from its default of 8 to 2 to yield 4 MHz
controller clock from the internal 8 MHz RC
oscillator by software,
1 ms clock: by dividing the controller clock
in the time/counter 1 prescaler by 8 and by
Clear-Timer-on-compare (CTC) by 500, with Compare
A set to 499, and compare match A interrupt,
Keys: Reading and processing of the keys in each
millisecond, with toggle protection following each
key event recognition,
Time measurement: If the stopwatch is running, each
compare match interrupt increases the time in ms in
the five registers and displays all times on line 1
of the LCD, if necessary (only the registers that
were changed during increase are displayed on the
Storage: Transfer of the current time in the
registers to a storage space in SRAM, shifting of
all stored times and display updates for lines 2 to
4 of the LCD.
2.1 Clearing the SRAM storage place
At start-up and when resetting the stopwatch the whole
storage area in SRAM has to be cleared, which means that
zeros have to be written there. As this part is executed
two times, it is formulated as a subroutine, so it can
be called from different addresses.
The routine uses the register pair ZH:ZL as pointer to
SRAM. It is set to the beginning of the storage space.
Clearing is done in a loop that writes, with the AVR
instruction st Z+,R16 the content of the register
(zero) to the storage byte addressed in register pair
ZH:ZL and automically increases the address in Z by one.
If the LSB of the Z pointer reaches the end of the
SRAM area to be cleared, the routine stops.
2.2 Shifting values in the storage space
In case the Store key has been pressed the
current time, located in five registers, has to be
copied into the SRAM,
all stored times have to be shifted by five bytes
to upper addresses, by that overwriting the last
five bytes (done with the subroutine Shift),
those shifted times have to be displayed in the
lines 2 to 4 on the LCD
2.2.1 Shifting of time information
Here is the storage space in SRAM with all addresses in
Shifting has to start from the end of the storage space
(by overwriting the last time stored) and has to move
backwards to lower addresses. The byte transfer is from
a source address (at the five byte lower address) to a
target address. So two pointers are required that differ
The two pointers are XH:XL or X for the source address
and ZH:ZL or Z for the target address.
The flow utilizes a specialty of the AVR instruction set:
with LD R16,-X the pointer X is first decremented
and after that copies the content of the SRAM at this
already decremented address to the register. Similarly
ST -Z,R16 first decrements the address in Z and
after that writes the register's content to the already
decremented location address in SRAM. This makes it easy
to read and write backwards, but you'll have to be aware
that both pointers, at the beginning, have to point one
position higher than were they first transfer from/to.
This operation has been programmed as a subroutine, too,
even though it is performed only once (when the Store
key is pressed). This eases simulation and debugging.
2.2.2 Displaying the shifted values
When displaying the three lines on LCD the following
The line counter ZH starts with 1 (on line 2)
and is increased for each displayed line (if it
reaches four, the display is done), as this
register is altered by other called subroutines
it is pushed to the stack and later restored (not
shown here). The column address ZL of the LCD
points to the tens of the hour to be displayed.
With that positioning is done for each line to be
The SRAM address of the time to be displayed is
held in X. Reading one byte of information
increases this address (LD rmp,X+ with
subsequent auto-incrementation) and therefore,
after five bytes have been read, is already on
the address of the next line's time information.
Displaying the time advances from the hour to
the minutes, then to seconds, centiseconds and
milliseconds. Except for the last, a routine
named Bin2Dec2 is used to convert the byte to
a 2-digit decimal and display those on the LCD.
In between hours and minutes and between minutes
and seconds a colon is added. Following the
seconds a decimal point is added.
The software has been written by Jochen Girschik
(translation by me) and is completely in assembler. The
source code can be viewed in browser format
from here in asm format.
Assembling requires that the
modified LCD include file
is stored within the same path.
Praise, error reports, scolding and spam please via the