Schon vor längerm hatte ich geplant eine Uhr mit einem AVR zu realisieren, auch damals mit einem Uhrenquarz (32,768kHz). Irgendwie wollte das Ding nicht genau werden, der Fehler betrug gleich mal 10min pro Tag was mich doch sehr wunderte.
Mittlerweile hatte ich wieder etwas Zeit für dieses Projekt gefunden, diesmal mit folgender Schaltung:

Natürlich war auch ein Display angeschlossen, der Übersichtlichkeit halber habe ich dessen Anschluss weggelassen.
Aber auch diesmal mußte ich feststellen, das die Uhr viel zu langsam war. Man konnte am Trimmer machen was man wollte, die Uhr war schlicht total ungenau. Diesmal wollte ich es aber nicht wahrhaben und nach genauer Lecktüre der Mega Dokumentation fand ich schließlich die U(h)rsache.
Die Fuse CKOPT war standardmäßig programmiert, dass heißt das interne 36pF Kapazitäten eingeschalten werden. Dadurch war natürlich die Spezifikation des Uhrenquarzes weit überschritten - deswegen auch die Ungenauigkeit in der Laufzeit.
Die wichtigsten Assemblerteile:
ldi r16, 0b00000101 ; Vorteiler für Timer2 = 128 -> 128*256 = 32768 also genau 1 Overflow je Sekunde
out tccr2, r16
ldi r16, 0b01000000; Overflow Interrupt von Timer 2 aktivieren
out timsk, r16
TIM2_OVF:
push r16 ; Arbeitsregister auf den Stack
in r16, sreg ; Wichtig, Sreg einlesen, da die CPI Befehle dort Bits ändern
push r16 ; und auf den Stack
inc r21 ; sekunde erhöhen
cpi r21, 60
brlo nothingtodo
clr r21 ; Sekunde ist 60, daher Löschen und Minute erhöhen
inc r22
cpi r22, 60
brlo nothingtodo
clr r22
inc r23 ; Stunde erhöhen
cpi r23, 24
brlo nothingtodo
clr r23
nothingtodo:
pop r16 ;Sreg vom Stack
out sreg, r16 ; und wieder zurückschreiben
pop r16 ; Arbeitsregister vom Stack holen
reti