Guten Morgen,
Meine Frage:
ich arbeite seit ein paar Wochen an einer Schaltuhr für die
Gartenbewässerung. Der Teil "Digitaluhr" funktioniert und geht auch sehr
genau (Abweichung ~1s in 72 Stunden). Diese Genauigkeit reicht für
meinen Anwendungsfall aus.
Ich habe nun erfolglos versucht den Code umzustellen und die Berechnung
der Uhrzeiten, Datum etc. in die Interupt-Routine zu schieben. Dabei
beobachte ich, dass die Laufzeit des Timers sich ändert, d.h. die mit
dem Zähler gemessene Zeit zwischen 2 High-Flanken an Pin5 (siehe
Interupt-Routine) ändert sich, wenn ich im if-Zweig der Interupt-Routine
Kommandos hinzufüge!!!
Meiner Erwartung nach, dürfte sich da aber nichts ändern solange ich
unter 40000 Taktyklen bleibe...
Was ist los? Habe ich den Timer falsch benutzt ? Stimmt der Mode?
Oder habe ich was übersehen ?
Die Fakten:
Dazu verwende ich dieses Konstrukt (ich hab die relevanten Teile
rauskopiert) und compiliere es fehlerfrei mit GCC:
#define F_CPU 4000000UL // Takt in Hertz
#define T_VAL 39974 // Mit Zähler abgeglichen auf 1,0000043s
ISR(TIMER1_COMPA_vect)
{
OCR1A = T_VAL;
TCNT1=0;
tri_cnt++;
if (tri_cnt>99) {
trigger=1;
tri_cnt=0;
//Debug 1.0000043s
PORTC |= (1<<PC5);
asm("nop");
PORTC &= ~(1<<PC5);
}
}
Im main wird der Timer so initialisiert:
TCCR1A = 0x00;
TCCR1B = 1<<WGM12 ^ 1<<CS10; // set CTC-Mode "4" + no prescaler
OCR1A = T_VAL;
TCNT1 = 0;
TIMSK = 1<<OCIE1A;
sei();
Alle 10ms wird in die Interupt-Routine gesprungen und der Timer neu
initialisiert (dies müsste doch Peters "Genaue Sekunde" entsprechen.
Danach wir der Zähler "tri_cnt" so lange erhöht bis er 100 ist. Die
Variable "trigger" verwende ich im Moment als Flag um im Hauptprogramm
die Uhrenberechnung und die Ausgabe aufs LCD zu steuern.
Gruß
Andreas
Im CTC-Modus wird der Timer automatisch zurückgesetzt. Das TCNT1 = 0 in der ISR ist auf jeden Fall fehl am Platz. Und da T_VAL ja ein Makro ist (also für einen konstanten Wert steht, der sich im Verlauf des Programms gar nicht ändern kann), ist es auch unsinnig, das jedes mal wieder ins OCR zu schreiben.
Hi, Du hast recht - die Einträge sind nicht notwendig. allerdings bleibt es dabei, dass sich die Laufzeit ändert ... Ist "ISR(TIMER1_COMPA_vect)" den für meinen Anwendungsfall richtig ??? Gruß Andreas
UBoot-Stocki wrote: > Du hast recht - die Einträge sind nicht notwendig. allerdings bleibt es > dabei, dass sich die Laufzeit ändert ... Nun, das ist so wie immer: Ohne ein einigermaßen komplettes Programm kann man nicht viel Sinnvolles sagen... > Ist "ISR(TIMER1_COMPA_vect)" den für meinen Anwendungsfall richtig ??? Sollte schon.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.