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


von Gast (Gast)


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:
1
// ---------------------------------------------------------------------------------------------------
2
// ------------------------------------- Modus: Live Übertragung -------------------------------------
3
// ---------------------------------------------------------------------------------------------------
4
5
    if(flag.live_active == 1)      // Live Übertragung aktiv?
6
    {
7
      flag.other_packet_receive = 0;            // Sicherheitshalber auf 0 zurücksetzen
8
      packet_counter = 0;                  // Sicherheitshalber auf 0 zurücksetzen
9
  
10
      live:                        // Goto Sprungmarke (aufpassen!)
11
      usart_new_line(measured_length,measured,rtc);    // Schicke "Neue Zeile"
12
      
13
      timeout_counter = 0;                // Setze Timeout-counter auf 0 (nach der Goto Marke)
14
      flag.timeout = 0;                  // Setze Timeout auf 0 (nach der Goto Marke)
15
16
      while(!usart_check())                // Warte bis über USART etwas empfangen wurde.
17
      {
18
        if(timeout_counter++ == 0xFF)          // Wurde kein Packet gesendet?
19
        {
20
          flag.timeout = 1;              // Es gab ein Timeout
21
          break;                    // Abbruch der Abfrage ob Packete erhalten
22
        }
23
      }
24
25
      if(flag.timeout == 1)                // Gab es ein Timeout?
26
      {
27
        if(flag.other_packet_receive == 1)        // 2 falsches Packet oder erstes? (schließt nur anderes Packet aus)
28
        {
29
          // FEHLERFALL:
30
          // Es wurde zuerst ein anderes Packet gesendet und jetzt kam es zum Timeout
31
          // Muss noch ausbauen
32
        }
33
        else                      // Es gab bis jetzt nur Timeouts
34
        {
35
          if(packet_counter >= 2)            // Wurden Daten schon 3 mal falsch gesendet?
36
          {  
37
            // FEHLERFALL:
38
            // Es wurden 3 "Neue Zeilen"-Packete geschickt, aber kein einziges ACK erhalten
39
            flag.live_active = 0;          // Live Modus wegen Fehler beenden
40
            programm_error(0xAA);          // ERROR !! richtigen Fehlercode noch ergänzen
41
          }
42
          else
43
          {
44
            // FEHLERFALL:
45
            // Es wuruden weniger als 3 "Neue Zeilen"-Packete geschickt, aber bis jetzt kein ACK erhalten
46
            packet_counter++;            // Erhöhe Fehleranzahl um 1
47
            goto live;                // Schicke Daten nocheinmal
48
          }
49
        }
50
      }
51
      else                        // Es wurde ein Packet erhalten (Kein Timeout)
52
      {  
53
        command_nr_live = usart_recieve_packet();    // Hole den Befehlscode
54
        if(COMMAND_RECEIVE_ACK == command_nr_live)    // Wurde richtiges Packet erhalten? (ACK)
55
        {
56
          flag.other_packet_receive = 0;        // Richtiges Packet erhalten
57
          command_nr_live = COMMAND_ZERO;        // Setze die Command Nr zurück
58
        }
59
        else
60
        {
61
          if (flag.other_packet_receive == 1)      // Ist das schon das 2te falsche Packet?
62
          {
63
            // FEHLERFALL:
64
            // Es wurde kein ACK sondern anderes Packet erhalten, schon zum 2ten mal
65
            flag.live_active = 0;          // Live Modus wegen Fehler beenden
66
            programm_error(0xAA);          // ERROR, den rictigen Fehlercode noch ergänzen
67
          }
68
          else
69
          {
70
            // FEHLERFALL:
71
            // Es wurde kein ACK sondern ein anderes Packet erhalten
72
            flag.other_packet_receive = 1;      // Falsches Packet erhalten
73
            goto live;                // Versuch es nocheinmal
74
          }
75
        }
76
      }
77
    }


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)

von H.Joachim S. (crazyhorse)


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.

von (prx) A. K. (prx)


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.

von Benedikt K. (benedikt)


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.

von Gast (Gast)


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!

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
Noch kein Account? Hier anmelden.