Forum: Compiler & IDEs Verständnisproblem Interupt-Routine: Wer hat Idee für Timi


von UBoot-Stocki (Gast)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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.

von UBoot-Stocki (Gast)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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
Noch kein Account? Hier anmelden.