www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie bekomme ich die Goto-Anweisungen weg?


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

Ich programmiere gerade ein USART Protokoll (PC zu µC Verbindung) und da 
habe ich ein kleines Problem:
Wenn ich das Packet "Neue Zeile" (new_line) wegschicke, dann erwarte ich 
mir vom PC, dass er mir ein ACK sendet. Allerdings könnte ja genau in 
diesem Moment der PC auch ein anderes Packet schicken (z.b. Live Modus 
Stopp). Und genau wegen dem und noch ein paar anderen 
Fehlerbehandlungen, habe ich einen Code geschrieben, wo Goto Anweisungen 
drinnen sind. Allerdings sollte man ja unter keinen Umständen diese Goto 
Anweisungen benutzen, ich weiß aber gerade nicht, wie ich die da 
rausbekomme!
Hier mal der Code:

// ---------------------------------------------------------------------------------------------------
// ------------------------------------- Modus: Live Übertragung -------------------------------------
// ---------------------------------------------------------------------------------------------------

    if(flag.live_active == 1)      // Live Übertragung aktiv?
    {
      flag.other_packet_receive = 0;            // Sicherheitshalber auf 0 zurücksetzen
      packet_counter = 0;                  // Sicherheitshalber auf 0 zurücksetzen
  
      live:                        // Goto Sprungmarke (aufpassen!)
      usart_new_line(measured_length,measured,rtc);    // Schicke "Neue Zeile"
      
      timeout_counter = 0;                // Setze Timeout-counter auf 0 (nach der Goto Marke)
      flag.timeout = 0;                  // Setze Timeout auf 0 (nach der Goto Marke)

      while(!usart_check())                // Warte bis über USART etwas empfangen wurde.
      {
        if(timeout_counter++ == 0xFF)          // Wurde kein Packet gesendet?
        {
          flag.timeout = 1;              // Es gab ein Timeout
          break;                    // Abbruch der Abfrage ob Packete erhalten
        }
      }

      if(flag.timeout == 1)                // Gab es ein Timeout?
      {
        if(flag.other_packet_receive == 1)        // 2 falsches Packet oder erstes? (schließt nur anderes Packet aus)
        {
          // FEHLERFALL:
          // Es wurde zuerst ein anderes Packet gesendet und jetzt kam es zum Timeout
          // Muss noch ausbauen
        }
        else                      // Es gab bis jetzt nur Timeouts
        {
          if(packet_counter >= 2)            // Wurden Daten schon 3 mal falsch gesendet?
          {  
            // FEHLERFALL:
            // Es wurden 3 "Neue Zeilen"-Packete geschickt, aber kein einziges ACK erhalten
            flag.live_active = 0;          // Live Modus wegen Fehler beenden
            programm_error(0xAA);          // ERROR !! richtigen Fehlercode noch ergänzen
          }
          else
          {
            // FEHLERFALL:
            // Es wuruden weniger als 3 "Neue Zeilen"-Packete geschickt, aber bis jetzt kein ACK erhalten
            packet_counter++;            // Erhöhe Fehleranzahl um 1
            goto live;                // Schicke Daten nocheinmal
          }
        }
      }
      else                        // Es wurde ein Packet erhalten (Kein Timeout)
      {  
        command_nr_live = usart_recieve_packet();    // Hole den Befehlscode
        if(COMMAND_RECEIVE_ACK == command_nr_live)    // Wurde richtiges Packet erhalten? (ACK)
        {
          flag.other_packet_receive = 0;        // Richtiges Packet erhalten
          command_nr_live = COMMAND_ZERO;        // Setze die Command Nr zurück
        }
        else
        {
          if (flag.other_packet_receive == 1)      // Ist das schon das 2te falsche Packet?
          {
            // FEHLERFALL:
            // Es wurde kein ACK sondern anderes Packet erhalten, schon zum 2ten mal
            flag.live_active = 0;          // Live Modus wegen Fehler beenden
            programm_error(0xAA);          // ERROR, den rictigen Fehlercode noch ergänzen
          }
          else
          {
            // FEHLERFALL:
            // Es wurde kein ACK sondern ein anderes Packet erhalten
            flag.other_packet_receive = 1;      // Falsches Packet erhalten
            goto live;                // Versuch es nocheinmal
          }
        }
      }
    }



Wenn irgendjemand nähere erklärungen zu dem Code benötigt, dann sagt es 
mir. Bitte helft mir diese Goto Anweisungen da raus zu bekommen, damit 
ich einen schöneren Code habe (ich möchte ja auch noch weiter etwas 
lernen! :D)

Autor: H.Joachim Seifert (crazyhorse)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach ja, das verteufelte goto....
Es ist manchmal eine sehr praktische Sache, mich stört es nicht, das zu 
benutzen, wenn es passt.
Prinzipiell geht es natürlich ohne.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
do..while mit flag.

Ich bin kein strikter Gegner von goto. Es gibt Fälle wo es 
übersichtlicher ist als die Alternative. Aber Schleifen sollten wie 
Schleifen aussehen.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich auch so. Solange man es sinnvoll einsetzt, ist dagegen nichts 
einzuwenden.
Ob der Compiler jetzt am Ende einer Schleife einen Sprung macht, oder ob 
man das über ein goto löst, läuft letztendlich auf das selbe hinaus.

Wenn du es unbedingt weghaben willst:
Eine Endlosschleife mit break bzw. continue wäre eine Möglichkeit. goto 
dürfte aber die besser verständliche Lösung sein.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke Leute, habe auch übrigens gerade einen Logikfehler da drin 
gefunden.


Warum schicke ich die zeile nochmal, wenn ich ein anderes packet 
erhalten habe? Da müsste ich doch nur schauen, was im nächsten packet 
ist... Aber egal! Danke!

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.