mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit der Endlosschleife


Autor: Tom Kräuter (tommy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Tom Kräuter (tommy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Ralf K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: GerhardB (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tom Kräuter (tommy)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Ralf K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Tom Kräuter (tommy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Andreas !

Wenn man die Variablen mit volatile deklariert dann läufts auch mit For
und While-Schleifen !

Tschüss
Tom

Autor: Andreas Fertl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum müssen die denn volatile sein?

Gruß Andreas

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil der Compiler sie sonst wegoptimiert.

Autor: Andreas Fertl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile gehört zum Standard.

Autor: Andreas Fertl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo :)
gehört dazu.
Ist im K&R Büchlein drinn....

ok das leuchtet ein dass er se wegoptimiert.

Thx.
Gruß Andreas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.