Applications of
AVR single chip controllers AT90S, ATtiny, ATmega and ATxmega A seconds/minutes/hours timer with a crystal and an ATtiny25
An ATtiny makes seconds, minutes and hour pulses with a crystal
Nearly every ATtiny or ATmega can be clocked with an external crystal. This
allows for exact timing. Here you'll find a simple device that produces
exact second, minute and hour pulses on the available port pins of an
ATtiny25,
1 Schematic of the pulse generator
This is merely the same as already described in tinyxtal.html,
but here the ATtiny25's three portpins provide output pulses of the desired durations.
All three outputs produce signals with 50% pulse width. That means that the seconds
output changes every 0.5 seconds its polarity, the minutes output every 30 seconds
and the hour output every 30 minutes.
2 Selecting the crystal
To identify suitable crystals and for easy assdembler source code I've made
the LibreOffice-Calc file
here. The sheet "xtals_tc0"
allows to select from commercially available crystals as well as some frequencies
of internal RC oscillators of AVRs. When selected you'll get all infos necessary
to init the software for the Timer/Counter TC0.
Seöected by default is a 32.768-kHz crystal for watches. These are avaiable in
6-by-2-mm round metal cases. The prescaler of TC0 is set to 256, its CTC divider
to 64 (Compare-A value: 63). Then we directly get a 0.5-second long pulse
(32,768 / 256 / 64 = 2 Hz). If that inverts the second output pin (e. g. by
writing a one to PINB's bit 0), we'll have a second pulse with 50% pulse width.
If you select a different crystal or frequency, an additional software counter
is needed to come to the one-second-pulse. This can either be an 8-bit or a
16-bit counter. 16 bits are needed for most of the higher frequencies as well
as in cases where a higher prescaler value doesn't fit. Now inversion of the
secound output portpin is only done if the counter reaches zero.
The parameters clock, cPresc8, cPrescBits8, cCtcDiv8,
cCompA8 and cSoftCnt8 for the selected clock frequency can be
marked, copied with Ctrl-C and inserted to the source code file with Ctrl-V.
The assembler source code provided does all the counting and switching with
those parameters.
As can be seen from the sheet, nearly all crystals are suitable for that
purpose. Only very few with exotic frequencies do not fit.
To minimze the load for the controller by interrupts, all prescaler- and
divider-values in the table are maximized. Only if elevated prescaler
values are not possible and do not deliver integer divider values, their
value is selected smaller. The sleep share of the controller is in any case
larger than 99.0%, supply current consumption can be minimized.
Those who want to use TC2 (or TC1 in an ATtiny25) instead of TC0, has to
know that this Timer/Counter provides additional prescaler values. In a few
cases those values enable to optimize prescaler- and divider values. Do not
forget to change the prescaler table values in the sheet according to those.
3 Assembler-Software
The software can be downloaded in assembler format here
and can be viewed in the browser here.
To be able to use the software for all cases of frequencies the software
has lots of .ifs and .endifs. These are only necessary if you select a
crystal that needs an 8- or 16-bit-downcounter. With a crystal of 32.768 kHz
you do not need all this. But: make sure then that your burner's hard-
and software can master clock frequencies below 8 kHz. Not all can handle
this.
When burning the fuses for a 32kHz-crystal the following has to be considered:
ATMEL's Studio 4.19 denies to burn flash memory with less than 5 kHz
clock (unclear what the reasons for this night be). Therefore assemble the
source code for this frequency and burn it into the flash with the default
frequency (before fusing the external crystal). As far as an external LED
is attached to PB0, PB1 and/or PB2 those blink very fast now.
Now clear the CKDIV8 fuse.
Now the minute LED blinks even eight times faster.
Now you can set the fuse for the externaö Low-Frequency-Crystal:
Now the second-LED blinks slowly and the others are off for a while.
If you want to change the source code, you'll have to proceed the same way
back: first change the clock fuse to the internal RC oscillator, then program
the flash and then alter the clock fuse to the Low-Frequency-Crystal.
4 Simulating the software
I simulate this with avr_sim.
First, adjust the clock frequency to the 32kHz crystal.
These are the three ports after init: all are output and all are low.
Please note that the prescaler in the counter is already at six. These are the clock
cycles that are necessary for processing the interrupt request and for the jump
to the vector table's address. The times that follow are displaced by these extra
clock cycles.
Note that the minute counter in R17 is at decimal 60. That means that after 60
such interrupts the minute output will go high, as each interrupt will be after
0.5 seconds.
With the next instruction in the interrupt service routine, SBI PINB,0,
the polarity of port pin PB0 changes.
The scope in avr_sim has realized the change already.
And the next instruction counts down the number of half-seconds.
When the next interrupt starts, one second has elapsed. The second port-pin-change
has been detected by the Scope. But the scope does not yet display the frequency.
This changes with the next change: the displayed frequency is at 1.000 Hz and at a
pulse width of 50%.
After 60 port-pin-changes on PB0 the minute LED is switched on.
After 60 seconds and 120 port-pin-changes the minute is complete.
Simply mounted on a breadboard. The ISP interface is as large as the rest
of the components.
The xtal is a commercially available watch crystal.
To see if anything functions as designed, three LEDs have been attached.
6 Applying the module
You can do lots of things with that time module.
But, before you consider to drive a CMOS digital clock with it: that works fine,
just attach two 60-counters and a 12- or 24-counter to it. But to get the correct
time at start-up the hour counters have to be preset to e.g. 20:00:00, which
can be done with 10-counters that have a preset input. And the six- and 24-detection
requires some additional AND gates.
It is better then to construct the whole clockwork with a larger AVR and to attach
the 7-segmenmt displays to the AVR, using multiplexing. Or you use an ATtiny24
and you display the time on a 8-character-LCD, which, even with a background
illumination, needs much lower current consumption than that of a 7-segment-display.
To alter the software from a half-second to a full-second interrupt, is a manageable
task then.