Probleme mit der Endlosschleife

OP #216414
Lesenswert?

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?
Angehängte Dateien:
Admin Persönliche Seite #216415
Lesenswert?

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.
Gast #216418
Lesenswert?

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
Gast #216420
Lesenswert?

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.
OP #216421
Lesenswert?

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

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
Admin Persönliche Seite #216423
Lesenswert?

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.
#216424
Lesenswert?

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...
Gast #216428
Lesenswert?

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

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?

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