Forum: Mikrocontroller und Digitale Elektronik Unterschied: IF und SWITCH Abfrage


von Draco (Gast)


Lesenswert?

Hab da wieder ein kleines Problem mit meinem Compiler oder ich bin 
einfach zu dumm. Im Grunde dürften doch beide Abfragen das selber 
bewirken, das bei der Abfrage der Var "display" die jeweilige Function 
aufgerufen wird:
1
     switch (display) {
2
           case 1 : display_1(); break;
3
           case 2 : display_2(); break;
4
           case 3 : display_3(); break;
5
           case 4 : display_4(); break;
6
           case 5 : display_5(); break;
7
     }

und diese Abfrage:
1
    
2
     if (display == 1) display_1();
3
     if (display == 2) display_2();
4
     if (display == 3) display_3();
5
     if (display == 4) display_4();
6
     if (display == 5) display_5();

Jedoch wird entweder die Switchanweisung ignoriert oder der break kommt 
falsch. Wenn break weg bleibt, dann rennt er die switchanweisung 
logischerweise durch. Mit break bleibt sie stehen und das display bleibt 
dunkel.

Sollte ich das break in die function (display_x()) integrieren?!

von Helmut L. (helmi1)


Lesenswert?

Geht es jetzt um das Multiplexen einer 7-Segmentanzeige ?
Sowas macht man im Timerinterrupt damit die Daten kontinuierlich 
ausgegeben werden.

Ansonsten muss du schon etwas mehr Code zeigen.

Gruss Helmi

von Tim S. (maxxie)


Lesenswert?

Die beiden Codefragmente bewirken nicht das Gleiche:

Bei deinem switch wird immer nur ein case angesprungen und bis zum 
nächsten break oder return abgearbeitet. Das break kannst du NICHT in 
die display_x() Funktionen ziehen.

Die if Anweisungen werden hintereinander geprüft. Sollte display seinen 
Wert in einer der display_x() Funktionen ändern, so kann auch noch ein 
anderer der Zweige ausgeführt werden.

Sollte display sich nicht verändern innerhalb der Funktionen, dann ist - 
bis auf den overhead des wiederholten Vergleiches - das Resultat beider 
Codeschnipsel identisch.

von Sven P. (Gast)


Lesenswert?

Äquivalent wären:
>
1
>      switch (display) {
2
>            case 1 : display_1(); break;
3
>            case 2 : display_2(); break;
4
>            case 3 : display_3(); break;
5
>            case 4 : display_4(); break;
6
>            case 5 : display_5(); break;
7
>      }
8
>

und

>
1
>      if (display == 1) display_1();
2
>      else if (display == 2) display_2();
3
>      else if (display == 3) display_3();
4
>      else if (display == 4) display_4();
5
>      else if (display == 5) display_5();
6
>

von Klaus W. (mfgkw)


Lesenswert?

soweit ich das hier sehe, sollten die beiden gleich sein
(falls display nicht eine globale Variable ist, die in den
Funktionen manipuliert wird).

Der Fehler liegt wohl woanders...

von Alex22 (Gast)


Lesenswert?

ich kann mich Tim Seidel nur anschließen. Sofern sich der Wert von 
"Display" während der Laufzeit nicht ändert sollte in beiden Fällen das 
gleiche passieren.

Erläutere bitte deine Aussage:
>Jedoch wird entweder die Switchanweisung ignoriert oder der break kommt
>falsch.

von Klaus (Gast)


Lesenswert?

Mein Codeextrapolator sagt mir, der Fehler ist in Zeile 42 deines 
Programms.

Falls du meinem Codeextrapolator nicht vertrauen solltest, poste doch 
bitte deinen Code :)

von Draco (Gast)


Angehängte Dateien:

Lesenswert?

Gut gut, aber erschlagt mich nicht wegen dem Nudelcode :D Ich versuche 
ja mein bestes zu geben, und irgendwann klappt das schon noch g

Da ist übrigens auch gerade mein zweites Problem (Display_4, Calc_Sp) Da 
soll die Spannung berechnet werden, jedoch schaffe ich es nur bis dato 
Ganzzahlwerte zu bekommen. Brauch aber 2 Nachkommastellen :/

von Klaus (Gast)


Lesenswert?

also die Variable display wird in den einzelnen Funktionen schonmal 
nicht verändert. Damit sind deine beiden Code-Varianten eigentlich 
identisch.

was bei einem case statement immer gut kommt zum debuggen, ist ein 
default label, welches sich irgendwie bemerkbar macht, damit zu sieht 
dass was schief gelaufen ist.

Welchen Compiler benutzt du eigentlich? GCC scheints nicht zu sein.

von Draco (Gast)


Lesenswert?

Gut, ich werfe das default Statement mal mit rein.

Meine Umgebung ist MicroC auf einem EasyAVR6 mit Atmega32.

von Sven P. (Gast)


Lesenswert?

Ich hätte als Compiler aber auch keine Skrupel, den folgenden Codeblock 
nicht zu übersetzen:
1
     if (richtung == 1 && temp_select <= 1) {
2
                  display++;
3
                  if(display == 6) display = 1;
4
                  delay_ms(50);
5
                  richtung = 0;
6
     }
7
     if (richtung == 2 && temp_select <= 1) {
8
                  display--;
9
                  if(display == 0 ) display = 5;
10
                  richtung = 0;
11
     }

'richtung' wird bei Programmstart auf 0 gesetzt und im 
Hauptprogrammfluss nie wieder verändert, also werden die Bedingungen der 
beiden if niemals wahr. Daher können sie bedenkenlos ausgelassen werden.

von Peter D. (peda)


Lesenswert?

Die Funktion Button() ist nirgendwo definiert.

Und bei:
1
delay_ms(300);
in einem Interrupt, kräuseln sich jedem Programmierer die Fußnägel.

Nimm besser eine fertige und bewährte Entprellroutine:
http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_type=project&item_id=1801


Peter

von Draco (Gast)


Lesenswert?

Sven P. schrieb:
> 'richtung' wird bei Programmstart auf 0 gesetzt und im
> Hauptprogrammfluss nie wieder verändert, also werden die Bedingungen der
> beiden if niemals wahr. Daher können sie bedenkenlos ausgelassen werden.

Ähm doch, oben im Interrupt. Bei Betätigung des Drehgebers wird die 
jeweilige Richtung (2 links, 1 rechts) in diese Variable gegeben. Damit 
bestimme ich ja auch was nun in der IF oder Switch Abfrage wahr ist.

Peter Dannegger schrieb:
> Die Funktion Button() ist nirgendwo definiert.

Braucht es bei MicroC nicht, ist dort in der Standartbibliothek 
definiert.

Peter Dannegger schrieb:
> in einem Interrupt, kräuseln sich jedem Programmierer die Fußnägel.

Ich weiß, ich weiß. Gut die 300 ms bei dem Knopf sind eigentlich 
unnötig. Jedoch komme ich bei den 100 ms des Drehgebers nicht drumrum. 
:/

von Stefan E. (sternst)


Lesenswert?

Draco schrieb:
> Sven P. schrieb:
>> 'richtung' wird bei Programmstart auf 0 gesetzt und im
>> Hauptprogrammfluss nie wieder verändert, also werden die Bedingungen der
>> beiden if niemals wahr. Daher können sie bedenkenlos ausgelassen werden.
>
> Ähm doch, oben im Interrupt.

Dann informiere dich mal über die Bedeutung von "volatile".

von Sven P. (Gast)


Lesenswert?

Anders formuliert: Steck den Finger auf den Anfang von main() und 
verfolge den Programmablauf. Du wirst feststellen, dass 'richtung' 
niemals einen neuen Wert erhält.

von Peter D. (peda)


Lesenswert?

Draco schrieb:
> Braucht es bei MicroC nicht, ist dort in der Standartbibliothek
> definiert.

Nütz bloß nix, wenn man kein MicroC hat.
Man weiß also nicht, was diese Funktion macht.


Peter

von Klaus (Gast)


Lesenswert?

schau mal in deiner Doku zu MicroC nach, ob man da auch volatile 
braucht. Bei GCC würde es hier definitiv fehlen.

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.