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
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.
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.
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
TKam schrieb: > 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. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Allgemeines_.C3.BCber_die_Interrupt-Abarbeitung
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
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.