switch geht nicht

Gast #1373829
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
Moderator Persönliche Seite #1373835
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.
Gast #1373838
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
Moderator Persönliche Seite #1373854
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.
#1373999
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.