Hallo,
ich hab mal wieder ein Problem mit der richtigen Anwendung von C.
Es handelt sich um eine einfache Uhr.
Bei meiner Hardware handelt es sich um Stromversorgung,ein
industriestandard-kompatibles LCD, einen 3,6864 Mhz Quarz mit 22pf
Kerkos und einen ATMEGA-8.
Ich wollte die Uhr mit einem Timerinterrupt von dem 16-bit Timer 1
laufen lassen. Da ich 3,6864 Mhz habe, nehme ich also einen Prescaler
von 1024 und einen Compare-Wert von 1799.
In der Hauptschleife lasse ich noch die Routinen für ein LCD laufen (mit
den Routinen aus dem GCC-Tutorial).
Im Interrupt setze ich nur einen Wert, den ich dann im Mainloop
verarbeite, also prizipiell mache ich da nicht viel.
Trotzdem scheint die Uhr etwa 50% zu langsam zu sein.
Woran könnte das liegen?
Hier mein Quellcode:
1
#define F_CPU 3686400
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
#include<stdlib.h>
6
#include"lcd-routines.h"
7
8
charc_hours,c_minutes,c_seconds;//Die aktuelle Zeit
9
10
charcounter1;//Eine Variable, die anzeigt, ob der Timer gepiept hat
Dass ich die timer_tick-Routine eingebaut habe, kommt daher, dass ich
noch eine Wecker-Funktion einbauen möchte.
Die beiden Anzeige-Routinen rühren daher her, dass ich ein wenig damit
experimentiert habe, alle Operationen in eine sprintf-Anweisung zu
packen. Leider scheint das noch langsamer zu sein...
Könnte das Zeitproblem vielleicht etwas mit den _delay_ms(100) zu tun
haben?
Ich würde mich freuen, wenn ihr mir weiterhelfen könntet.
Mit freundlichen Grüßen,
Valentin Buck
Valentin Buck schrieb:> Ich wollte die Uhr mit einem Timerinterrupt von dem 16-bit Timer 1> laufen lassen. Da ich 3,6864 Mhz habe, nehme ich also einen Prescaler> von 1024 und einen Compare-Wert von 1799.
Wie kommst du auf 1799?
Wenn dein Haupttakt 3686400 Takte pro Sekunde sind
und du einen Vorteiler von 1024 benutzt, dann macht der
Timer logischerweise 3686400 / 1024 = 3600 Zählvorgänge in der Sekunde
und nicht 1800
Tada. Da ist dein Faktor 2
Ich hab mal die Interrupts in einer Minute gezählt.
Da kamen statt 60 nur 30 raus.
Ich hab dann mal den OCR-Wert halbiert(also auf 899) - und es
geht(fast)!
Leider jetzt 6 Sekunden zu schnell...
@Karl heinz Buchegger:
Laut der Formel im Datenblatt ist die Frequenz des CTCs
f_clk
f= ----------------------
2*Prescaler*(1+OCRnA)
-> 1799
Geht irgendwie aber nicht
@Falk Brunner
Danke, jetzt funktionierts auch!
Allerdings mache ich mir auch noch Sorgen um die LCD-Anzeige:
Wie kann ich statt
0 : 0 : 0
00 : 00 : 00
anzeigen lassen?
Im Moment wird, sobald die Sekunden einmal durch sind immer nur die
erste Stelle geändert. Die 9 bleibt steht stehen!
Könnt ihr mit da helfen?
mit freundlichen Grüßen,
Valentin Buck
Valentin Buck schrieb:> Ich hab mal die Interrupts in einer Minute gezählt.> Da kamen statt 60 nur 30 raus.> Ich hab dann mal den OCR-Wert halbiert(also auf 899) - und es> geht(fast)!> Leider jetzt 6 Sekunden zu schnell...
Die Zahl ist komplett daneben.
Kontrolliere mal, ob dein Quarz überhaupt aktiv ist.
> @Karl heinz Buchegger:> Laut der Formel im Datenblatt ist die Frequenz des CTCs> f_clk> f= ----------------------> 2*Prescaler*(1+OCRnA)
Du schreibst jetzt 100 mal:
Ich soll nicht einfach stumpfsinnig Fomeln aus dem Datenblatt
abschreiben.
Die Formel ist gedacht für
ISR( ... )
{
toggle Output Pin
}
Da daher 2 ISR Aufrufe erfolgen müssen, um 1 Schwingung zu erzeugen,
taucht der 2er in der Formel auf.
Die Wette steht, dass dein Quarz zur Zeit noch gar nicht aktiv ist, d.h.
dein µC noch mit rund 1Mhz arbeitet. Probiers mal mit 976, da wirds dann
ziemlich gut stimmen (oder auch nicht, je nach Umgebungstemperatur)
1000000 / 1024 = 976.56
> Allerdings mache ich mir auch noch Sorgen um die LCD-Anzeige:> Wie kann ich statt> 0 : 0 : 0> 00 : 00 : 00> anzeigen lassen?
sprintf( buffer, "%02d:%02d:%02d", stunde, minute, sekunde );
(Du brauchst auch noch ein C-Buch)
Ohhhh, natürlich!
Der externe Quarz...
Jetzt gehts!
Mit den 3600.
Ich glaube, ich habe verstanden, wie man die Zyklen berechnet.
Die Ausgabe hab ich jetzt auch geändert - funktioniert auch!
Welches C-Buch ist denn gut?
(bisher orientierte ich mich eher am Internet,
aber was auf Papier ist doch besser...)
Mit freundlichen Grüßen,
Valentin Buck
@Valentin Buck (nitnelav)
>Welches C-Buch ist denn gut?
Die Klassiker, K&R, Programmieren in C. Oder einen der diversen Ableger,
sind auch OK.
http://www.mikrocontroller.net/buecher/
MFG
Falk