Verständnisproblem Interupt-Routine: Wer hat Idee für Timi

Gast #594834
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
#594861
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.
Gast #595155
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
#595190
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.