Also wollte mal wieder ein wenig herumspielen mit WinAVR udn ein kleines Programm schreiben, welches folgendermaßen aussieht (die verwendete UART.c hab ich nicht inkludiert, da diese mit dem Problem denke ich nichts zu tun hat) int main(void) { init_uart(); unsigned int wert,overflows,timerstand = 0; unsigned char buffer[10]; uart_puts("Controller online..... OK\n\r"); TCCR0 = _BV(CS00) | _BV(CS02); //1024 prescaler TIMSK = _BV(TOIE0); //Timer0 Overflow Interrupt Enable sei(); // enable all interrupts while(1) { if(wert == 10) { uart_puts("Timerstand:"); itoa(timerstand,buffer,10); uart_puts(buffer); wert = 0; } } ISR(TIMER0_OVF_vect) { overflows++; timerstand = TCNT0; if(overflows == 256) { wert++; uart_puts("Wert wurde um 1 erhöht!"); } } } Das ich hier den Timerstand ausgebe, ist natürlich Unsinn und hat keine spezielle Funktion. SOllte nur zum Testn sein.. Im main programm sollte in der Endlosschleife der leztzte erfasste TImerstand rausgesendet werden. Die if Abfrage in der ISR und im Main Programm sollten nur eine Verzögerung bewirken, d.h. das der Timer öfter überlaufen muss, um ein wenig Zeit zu gewinnen.... Tatsache ist, dass der Timerstand NIE ausgegeben wird, das Programm hängt jedoch in einer Endlosschleife, wo es nicht sollte.. denn es wird der String "Controller online..... OK (sollte nur einmal bei Beginn gesendet werden) in einer Endlosschleife rausgeschickt und sonst gar nichts... Ich nehme an, es ist wieder ein typischer Anfängerfehler, jedoch komm ich nicht dahinter... Danke im Voraus!
P.S.: Ich habe den Verdacht, dass da irgendwas wegoptimiert wird?! Muss ich da irgendwo ein "static volatile" oder sowas in der Art benutzen?? Und warum läuft der in einer "anderen" Endlosschleife?!
"timerstand" sollte in der Tat volatile sein, da er zwischen einer ISR und dem Hauptprogramm Daten austauscht. Du hast versucht, eine ISR innerhalb einer Funktion geschachtelt zu definieren. Bitte definiere sie auf der obersten Ebene.
Eine ISR innerhalb einer Funktion geschachtelt zu definieren? Wie ganau meinst du das? Das die ISR in der Funktion main() steht ? Sollte die ISR vor dem main() stehen? Was ich noch wissen möchte, in welcher Reihenfolge beginnt der Compiler beim Übersetzen? Ich dachte immer bei main()..... Denn wenn ich z.B.: die ISR ISR(interrupt) { ... } Außerhalb von main() schreibe, bekomme ich Fehler, dass er bestimmte Variablen nicht kennt... Wenn das main Programm aber schon übersetzt wurde, müsste er die doch Variablen kennen....?! Wie ist das dann, wennd die ISR vor dem Hauptprogramm steht?! Danke!
Ja du solltest sie vor der Main definieren. Und damit er auch dann die Variablen kennt, definiere sie als globale volatile Variablen. Eigentlich sollte man doch alle Funktionen vor der Main definieren oder nicht? Gruß Marian
Variablen, die im IR benutzt werden, müssen global declariert werden, d.h. sie müssen ausserhalb einer Funktion (in Deinem Fall main) stehen. Variablen, die innerhalb einer Funktion stehen, werden auf dem Stack angelegt. Die Stackadresse kann aber bei jedem Aufruf der Funktion unterschiedlich sein. Deine Interrupt-Funktion "weiss" also nicht, an welcher Adresse die Variable steht. Was bei Dir auch fehlt, ist die Declaration als volatile. Siehe diverse BEschreibungen dazu hier im Forum. Probier Deinen Code so umzubauen: //*** Variablendeklaration ausserhalb einer Funktion: **** volatile unsigned int wert,overflows,timerstand = 0; volatile unsigned char buffer[10]; int main(void) { .... } ISR(TIMER0_OVF_vect) { .... } Gruß, Stefan
ISR im Besonderen, sonst kann man sie nur während der Laufzeit der Funktion in der sie definiert sind erreichen. Das dürfte zum sicheren Absturtz führen , wenn der IRQ mal eben vorher vorbeikommt. ;-)
Bin noch nie auf die Idee gekommen, Funktionen innerhalb von Funktionen zu definieren. Wer mit Assembler angefangen hat, macht sowas nicht, denn da gehts definitiv schief. Wußte garnicht, daß sowas überhaupt geht. Warscheinlich wird dann die Funktion nicht mehr als Interrupthandler erkannt, denn für einen freigegebenen Interrupt ohne Handler ist es typisch, daß das Programm immer wieder von vorne anfängt. "Was ich noch wissen möchte, in welcher Reihenfolge beginnt der Compiler beim Übersetzen? Ich dachte immer bei main()....." Nein. Er übersetzt immer von oben nach unten und von links nach rechts bzw. entsprechend den Vorrangregeln. Peter
Ok, alles klar...Danke für alle Antworten, werde das heute ändern und nochmal probieren! Thx!
Ok, nach diesen Umstellungen/Korrekturen läuft alles so , wie ich mir das gedacht habe! Jetzt werd ich mich noch damit beschäftigen, wie ich genaue delays (z.B.: genau eine schöne sekunde lang) erzeuge und was für timermodi es alles gibt bzw. wo man die einsetzt! Das mit dem capture/compare oder CTC mode ist mir noch zu hoch ;-) Ein Danke an alle
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.