www.mikrocontroller.net

Forum: Compiler & IDEs switch geht nicht


Autor: leone (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>

unsigned int iState;

int main(void)
{

  PORTB = 0xFF;    // pull ups for key inputs  PortD2 and portD3
  
  DDRC = 0xFF;     // outputs for LEDs
  PORTC = 0xFF;    // LEDs off
  
  iState = 0;
  for(;;)
  {
  if (iState != PINB)  // Key state changed ?
  {
    _delay_ms(50);  // dirty "debounce"

    switch (PINB)
    {
      case 0x01:
        PORTC = 0x01;
    break;

      case 0x02:
        PORTC = 0x02;
    break;

      default:   // no key
      PORTC = 0xFF;

   };
     }
}    

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

gruß
Leone

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <avr/io.h>

int main(void)
{

  PORTB = 0xFF;    // pull ups for key inputs  PortD2 and portD3

  DDRC = 0xFF;     // outputs for LEDs
  PORTC = 0xFF;    // LEDs off

  for(;;)
  {
    PORTC = PINB;
  }
}

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.

Autor: Penie Lydos (peniely)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: leone (Gast)
Datum:

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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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:
goto jump_into_loop;

do {
   ...
   jump_into_loop:
   ...
} 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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. :)

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.