Forum: Compiler & IDEs switch geht nicht


von leone (Gast)


Lesenswert?

Hallo,

der folgende Quellcode funktioniert nicht, und ich weiß nicht wieso.
Eigentlich sollte der richtig sein, doch bei der switch-Anweisung
springt er immer zur Default. und wird auch korrekt aufgerufen.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
5
unsigned int iState;
6
7
int main(void)
8
{
9
10
  PORTB = 0xFF;    // pull ups for key inputs  PortD2 and portD3
11
  
12
  DDRC = 0xFF;     // outputs for LEDs
13
  PORTC = 0xFF;    // LEDs off
14
  
15
  iState = 0;
16
  for(;;)
17
  {
18
  if (iState != PINB)  // Key state changed ?
19
  {
20
    _delay_ms(50);  // dirty "debounce"
21
22
    switch (PINB)
23
    {
24
      case 0x01:
25
        PORTC = 0x01;
26
    break;
27
28
      case 0x02:
29
        PORTC = 0x02;
30
    break;
31
32
      default:   // no key
33
      PORTC = 0xFF;
34
35
   };
36
     }
37
}

Bin echt für jede Hilfe dankbar, denn so langsam zweifel ich an meinem
Verstand.

gruß
Leone

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich fürchte, der Code wird funktionieren, nur deine Eingänge
lesen nicht das zurück, was du erwarten würdest.

Reduzier das Programm doch erstmal auf einen einfachen Mirror, der die
Eingänge von PINB auf die Ausgänge von PORTC spiegelt.  Da du ja LEDs
dran hast an C, solltest du auf diese Weise gut erkennen können, was
denn genau an PINB reinkommt.
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
6
  PORTB = 0xFF;    // pull ups for key inputs  PortD2 and portD3
7
8
  DDRC = 0xFF;     // outputs for LEDs
9
  PORTC = 0xFF;    // LEDs off
10
11
  for(;;)
12
  {
13
    PORTC = PINB;
14
  }
15
}

p.s.: Meine Glaskugel sagt übrigens, dass deine Eingänge einfach nur
low-aktiv sind, d. h. du musst entweder mit ~PINB arbeiten oder
statt 0x01, 0x02 usw. auszuwerten 0xFE, 0xFD usw.

von Penie L. (peniely)


Lesenswert?


von Ralf (Gast)


Lesenswert?

Im DEFAULT fehlt das break. Vielleicht bringt ihn das durcheinander.
Und dann wäre noch die Frage, ob du zufällig die Taster nach GND 
angeschlossen hast (was man üblicherweise so macht), in dem Fall musst 
du dann in den CASE-Anweisungen den invertierten Wert abfragen.

Ralf

von leone (Gast)


Lesenswert?

vielen Dank an euch beiden
Auf dem Link war das Problem schon gelöst
Gruß
leone

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf schrieb:
> Im DEFAULT fehlt das break. Vielleicht bringt ihn das durcheinander.

Der letzte Label in einem switch benötigt kein break.  Wenn der
,,nach unten durchfällt'', ist die switch-Anweisung ja so oder
so beendet.

Es ist dabei übrigens völlig egal, ob der letzte Label nun "default"
heißt, oder ob es ein benannter Label ist (und default vielleicht
mittendrin geschrieben wird): entscheidend ist dabei nicht der Name,
sondern dass es der letzte innerhalb des switch ist.

ObJoke dazu: http://de.wikipedia.org/wiki/Duff's_Device
Eine sehr kreative Variante, sich die Eigenheiten der Programmier-
sprache C auszunutzen. ;-)  Selbst gestandene C-Hasen werden dabei
nicht auf Anhieb sagen können, was dort eigentlich wirklich passiert.

von Stefan E. (sternst)


Lesenswert?

Jörg Wunsch schrieb:

> ObJoke dazu: http://de.wikipedia.org/wiki/Duff's_Device
> Eine sehr kreative Variante, sich die Eigenheiten der Programmier-
> sprache C auszunutzen. ;-)  Selbst gestandene C-Hasen werden dabei
> nicht auf Anhieb sagen können, was dort eigentlich wirklich passiert.

Weil selbst gestandene C-Hasen gerne verdrängen, was die 
switch-Anweisung eigentlich ist, nämlich ein bedingtes goto. Der Code im 
switch sind eben nicht mehrere Blöcke mit der optionalen Möglichkeit in 
den nächsten Block "durchfallen" zu können. Es ist nur ein einziger 
großer Codeblock mit mehreren Einsprungpunkten und der optionalen 
Möglichkeit, ihn vorzeitig verlassen zu können (per break). Wenn einem 
das klar ist, ist auch sonnenklar, was dort passiert, denn mit folgendem 
hätten diese C-Hasen ja vermutlich kein Verständnisproblem:
1
goto jump_into_loop;
2
3
do {
4
   ...
5
   jump_into_loop:
6
   ...
7
} while (...);
Und das ist es, was dort passiert.

Ja, ich weiß, dir brauch ich das nicht zu erzählen. ;-)
Aber vielleicht hilft es ja jemanden, der hierüber stolpert.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ja, die Erklärung im Wikipedia fand ich so schlecht auch nicht.

Nur, wenn man das Teil das erste Mal sieht, knallt's einem doch ganz
mächtig an den Kopf. :)

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.