Timer0 und Timer2 simultan - ATMega32

Gast #1309943
Lesenswert?

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 #1310017
Lesenswert?

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!
#1310046
Lesenswert?

* 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 #1310051
Lesenswert?

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
#1310161
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren