Timer0 und Timer2 simultan - ATMega32

Gast #1309943
Hallo Leute,

bin ein GCC noob und ich habe ein Problem, wenn ich Timer 0 und Timer 2 
simultan initialisiere.

Ich moechte Timer 0 und 2 simultan etwas rechnen lassen und konfiguriere 
sie als compare interrupts:

    //Timer 0 und Timer 2 konfigurieren
    TCCR0 = (1<<WGM01) | (1<<CS01);
    OCR0 = 2;
    TCCR2 = (1<<WGM21) | (1<<CS21);
    OCR2 = 2;
    //Compare Interrupts 0 und 2 aktivieren
    TIMSK = (1<<OCIE0) | (1 << OCIE2);

Die Interrupt-Routinen inkrementeiren lediglich jeweils einen Integer:

    ISR(TIMER0_COMP_vect)
    {
        i++;
    }

    ISR(TIMER2_COMP_vect)
    {
        j++;
    }

In meiner main gebe ich in einer Schleife die Werte von i und j auf 
meinem LCD aus:

    for(;;) {
        set_cursor(0, 2);
        itoa(i,LcdBuffer,10);
        lcd_string(LcdBuffer);//lcd_string("  ");

        set_cursor(0, 3);
        itoa(j,LcdBuffer,10);
        lcd_string(LcdBuffer);//lcd_string("  ");
    }

Das Merkwuerdige ist, dass j staendig inkrementiert wird, aber i nicht; 
i hat permanent den Wert 0.

Und jetzt kommt's: wenn ich die Kommentare lcd_string("  "); nach der 
Ausgabe von i und j wieder in den Quellcode reinnehme, wird die 
Interrupt-Routine des Timers 0 EINMAL ausgefuehrt, denn i nimmt ab dann 
konstant den Wert 1 an.

Kann mir jemand erklaeren, womit das zu tun hat? Warum wird Timer0 nicht 
korrekt ausgefuehrt? Die main.c befindet sich im Anhang.

Vielen Dank im Voraus und schoene Gruesse,
Thomas
Angehängte Dateien:
Gast
Nur fuer den Fall, dass ich etwas in der Makefile verhauen habe, haenge 
ich sie auch nochmal an.

Die LCD-Routinen habe ich aus dem gcc-tutorial von hier.
Angehängte Dateien:
Gast
Vielen Dank fuer die schnelle Antwort.

Ich habe mal probiert, i und j als volatile unsigned int zu deklarieren, 
aber das Problem tritt nach wie vor auf. Worin besteht denn der 
Unterschied dazu, wenn ich i und j einfach als uint8_t deklariere?

Ich bin fuer jede Hilfe Dankbar!
* das volatile muss rein

* Wenn ich das recht sehe, dann lässt du beide Timer mit Full-Speed im 
CTC Modus laufen und setzt einen Compare Wert von 2.
Das heist aber auch, dass alle 3 Takte ein Interrupt ausgelöst wird.

D.h. Der Timer2 macht dir mit seinen Interrupts alles andere dicht. 
Sobald der Interrupt abgearbeitet ist, ist auch schon der nächste 
Interrupt von diesem Timer da. Dein Hauptprogramm schleppt sich mit Ach 
und Krach durch die Hauptschleife, praktisch ständig von der Interrupt 
Bearbeitung für Timer2 unterbrochen. Der Interrupt vom Timer0 kommt da 
gar nicht mehr durch.

Änderungen:
i und j als volatile definieren.
die OCR Werte höher setzen.
Gast
Wow, das ist ja interessant.

Ich dachte fuer Interrupt-Routinen wird (egal wo) immer unterbrochen. 
Dass sich 2 Timer wegen der Zeiten in die Quere kommen, haette ich daher 
nicht vermutet.

Aber das Hochsetzen der OCRx-Register hats echt gebracht.

Herzlichen Dank an die schnelle Hilfe, Karl heinz und Magnus, und 
schoene Gruesse!
Thomas
Hallo,

TKam schrieb:
> Wow, das ist ja interessant.
>
> Ich dachte fuer Interrupt-Routinen wird (egal wo) immer unterbrochen.
> Dass sich 2 Timer wegen der Zeiten in die Quere kommen, haette ich daher
> nicht vermutet.

Prinzipiell ist es auch so, wie Du schreibst.
Praktisch denke einfach darüber nach, wieviel Taktzyklen nötig sind, um 
Deine Befehle zu bearbeiten und wie oft Dein Interrupt auftritt.

Auch ein AVR kann immer nur einen Befehl nach dem anderen bearbeiten,
wenn eine Interruptroutine aufgerufen wurde, ist eben niemand da, der 
sich um den IRQ des 2. Timer oder um die Bearbeitung der main kümmern 
könnte.

Gruß aus Berlin
Michael

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.