Hallo Leute ! Ich benutze in meiner Main function goto label als Endlosschleife, da gibt es auch keinerlei Probleme mit dem Timer-Interupt!!! Doch wenn ich while(1) { } oder for(;;) als Endlos-Schleife benutzte funktioniert der Timer-Interrupt nicht mehr. Das Programm verbleibt in der main-Function!! Könnt mir weiterhelfen?
Könntest du das bei Gelegenheit etwas lesbarer formatieren? Dann kann man die Programmstruktur viel leichter erkennen. Schau dir mal ein paar Beispiele an, und achte drauf entweder nur Tabs oder nur Leerzeichen zu verwenden, aber nicht beides. Und das Goto scheint mir so überflüssig wie ein Kropf; das kann man doch alles ins case-Statement packen.
Was soll denn das hier: switch (phase) { case 1: goto label_1; break; case 2: goto label_2; break; case 3: goto label_3; break; case 4: goto label_4; break; case 5: goto label_5; break; case 6: goto label_6; break; } Man kann das ganze sicherlich noch unübersichtlicher programmieren, aber was bitte hat goto in einem switch-Statement verloren?
Okay an der Formatierung kann sicherlich noch was ändern. Aber was mit der While-Schleife im main-Program ? Wieso lässt sie kein Timer-Interrupt zu ?
Hi Tom, also ich würde mal wie üblich auf Stacküberlauf tippen. Einfach mal HW und SW Stack höher setzen. Kann auch sein, daß die Interruptroutine einfach zu lange braucht. Miss mal die Zeit nach, die die IR Routine braucht. Als Problemlösung schlanker und schneller machen, am besten in Assembler. Viel Erfolg lg Ralf
Mal nichts überstürzen. Für eine Ampelsteuerung ist ganz bestimmt kein Assembler notwendig. Tom, setz erst mal die Vorschläge um, dann löst sich das Problem vielleicht von ganz alleine, und vorher wird sich auch niemand das Programm genauer anschauen wollen.
Hallo Tom Da Dein Programm nichts anderes macht oder tun muss, als glegentlich den Code der Interrupt Routine auzuführen, würde ich den Code der ISR in die Hauptschleife verfrachten. Mit einem Timer würde ich eine Uhr realisieren (z.B. long SysTicks). Diese liesse sich dann einfach laufend abfragen. Dein Programmode wird dadurch auch viel robuster. Mir scheint es nämlich aus so, dass die Ursache für Dein Problem eine zu komplexe ISR ist. Beste Grüsse Gerhard Eine Ampelsteuerung wäre übrigens ein "schönes" Beispiel für eine State-Machine. Nach diesem Gesichtspunkt könnte man das Programm auch sehr gut lesbar machen.
Ich weiß nicht,ob ihr mein Problem richtig verstanden habt! Wenn ich in der main-Funktion goto - Schleife einbaue, läuft alles einwandfrei ! void main(void) //Hauptprogramm { init(); loop: PORTB = temp; PORTD = temp2; if bit_is_clear(PINB,7) // ( !(PINB & (1<<PINB7)) ) { temp2 &= ~ (1<< PD1) ; // PD1 wird auf Low Taster_gedrueckt = 1; // Taster wurde betätigt } goto loop; // Endlosschleife } Verwende ich jedoch ich einen While oder-for Schleife wird die Interruptroutine nicht aufgerufen!
Das sieht nach einem Compilerfehler aus. Um der Sache genau auf den Grund zu gehen müßtest den Code disassemblieren und den Fehler suchen. Bei den AVR Compilern kommen leider hin und wieder Compilerfehler vor und dann geht nur ausprobieren und tüfteln, meine Erfahrung. lg Ralf
Ein Fehler bei einem so simplen Stück Code ist so unwahrscheinlich dass man von einem Fehler beim Anwender ausgehen kann, und nach einem Blick auf dem Code wird der auch schnell klar: Variablen die in Interruptroutinen und Hauptprogramm verwendet werden müssen als volatile deklariert werden. Vermutlich wird goto bei der Optimierung etwas anders behandelt als eine Schleife, deshalb funktioniert es in dem einen Fall und in dem anderen nicht.
Das ist die längste ISR, die ich jemals gesehen habe. Erinnern tut mich das Programm an eins, das ein Freund vor Jahren (damals war der 286er richtig gut und teuer...) geschrieben hat. Ihm war wohl auch die Existenz von Feldern bekannt. So würde ich es machen: Ein Feld (aus Konstanten) mit den sechs Phasen erzeugen. Mit der Timer-ISR einfach den Phaseindex hochzählen, wenn er zu groß ist zurück auf 0 setzen. Scheinbar (dank der fehlenden Dokumentation noch schwieriger herauszufinden) handelt es sich um eine Bedarfsampel, die auf Tastendruck erst startet. In der Main wird also einfach die Ampel initialisiert (rot für Fußgänger, grün für Kfz). In einer Schleife wird solange abgefragt, ob die Taste gedrückt wurde, bis sie gedrückt wurde. Jetzt wird der Timer gestartet. In einer weiteren Schleife wird geprüft, ob sich der Phasenindex dank eines Timer-Überlaufs geändert hat Entsprechend wird die Konstante an den Port geschrieben. Die Schleife wird abgebrochen, sobald der Phasenindex bei der letzten Phase angekommen ist. Dann landet das Programm wieder in der "aufdieTastendrück"-Warteschleife. In der ISR wird der Phasenindex inkrementiert und der Timer-Reload-Wert neu gesetzt. Viel Code ist das nicht. Man braucht definitiv kein goto. Eigentlich sollte man die Benutzung dieses Wortes unter Strafe stellen. Zuletzt habe ich es gebraucht, als auf dem Apple][ noch ein Basic-Interpreter arbeitete. Der Rechner verstand auch noch keine Funktionsaufrufe...
Danke Andreas ! Wenn man die Variablen mit volatile deklariert dann läufts auch mit For und While-Schleifen ! Tschüss Tom
holla, is es net so dass ich ne variable volatile setzte wenn se von aussen (z.B. ein polling eines pins durch einen interrupt) gesetzt werden? @Tom Mach die gotos raus, das is wirklich nicht toll. Du benutzt doch eh schon states warum dann noch goto? Gruß Andreas
Variablen, die "von aussen" sichtbar sein sollen, müssen global vereinbart werden. Volatile weist den Compiler nur an, die Variable zu übersetzen, auch wenn er dafür in diesem Moment keine Verwendung sieht. Ist sie nicht als volatile vereinbart, und der Compiler sieht keine Verwendung, dann optimiert er sie weg. (Suchfunktion des Forums zum Thema "volatile"). volatile gehört ja auch nicht zu Standard-C, oder?
jo :) gehört dazu. Ist im K&R Büchlein drinn.... ok das leuchtet ein dass er se wegoptimiert. Thx. Gruß Andreas
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.