www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit der Case switch anweisung


Autor: Lord_Gismo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich Denke gerade über einem Problem nach, wo ich zu keiner andern Lösung 
mehr komme als das Forum hier zu benutzen. Und zwar geht es um die 
Switch Case Anweisung. Ich wollte ein Programm schreiben welches ,je 
nach Eingabe, verschieden Muster aufruft .Das Programm soll eigentlich 
nicht wirklich was machen es soll nur ein Test sein für die Switch Case 
anweisung.
int main (void)

{
char out1[8] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
char out2[8] ={0xfe,0xfd,0xfb,0xf7,0xEF,0xDF,0xBF,0x7F};
int p,i,a=200;


DDRD=0xff;
PORTD=0xff;
DDRB=0x00;
  while(1)
  {
  p=PINB;
    switch(p)
    {
    case 0x00:
  
      for(i=0;i<=7;i++)
        {
        PORTD=out1[i];
        _delay_ms(a);
        }
  
      for(i=7;i>=0;i--)
        {
        PORTD=out1[i];
        _delay_ms(a);
        }
    break;

    case 0x01:
      for(i=0;i<=7;i++)
        {
        PORTD=out2[i];
        _delay_ms(a);
        }
  
      for(i=7;i>=0;i--)
        {
        PORTD=out2[i];
        _delay_ms(a);
        }
    break;
    }  
  }
return(0);
}

Nun habe ich das ganze auf das STK500 geladen den PortD mit den LED's 
verbunden und den PINB 0 fest auf die 5V gelegt.Und es Passiert rein gar 
nichts auch nicht wenn man PINB 0 auf GND legt.Ich weiß aber das die 
For-Schleifen alle arbeiten wenn man sie ohne Switch-Case ablaufen 
lässt.
Ich weiß das ist ein Noob-Problem aber ich bitte nur die zu Antworten 
die wirklich helfen wollen. Ich habe auch schon die SuFu genötigt 
genauso hab ich Google gefragt aber das Problem nicht wirklich lösen 
können.
Villeicht sieht ja einer von Euch meinen Denkfehler in der ganzen 
Geschichte.Programmieren tue ich mit dem AVR-Studio und dem aktuellen 
WINAVR. Die Optimirungstufe ist auf -01 gestellt. Als µC wird der 
ATMEGA8 benutzt.

Danke fürs Durchlesen

Gruß

Gismo

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du nur PINB Bit 0 auf 0 oder 5V legst, weiß du noch nicht
welchen Wert die anderen Bits haben.
Wahrscheinlich kommst du gar nicht auf die Werte 0x00 oder 0x01,
sondern auf irgendwelche anderen.

Leg doch mal alle 8 auf 0 oder 5V, was passiert dann?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bzw. ändere dein switch so ab:
    switch(p&0x01)
Dadurch testet du nur das unterste Bit, und die anderen 7 sind egal.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Lord_Gismo (Gast)

>Switch Case Anweisung. Ich wollte ein Programm schreiben welches ,je
>nach Eingabe, verschieden Muster aufruft .Das Programm soll eigentlich
>nicht wirklich was machen es soll nur ein Test sein für die Switch Case
>anweisung.

Nimm ein zweidimensionales Feld, das ist deutlich einfacher. Und ein 
_delay_ms() mit variablem Paramter funktioniert nicht wirklich.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Besser so.
void var_delay(uint16_t ms) {
    for (; ms>0; ms--) _delay_ms(1);
} 
int main (void) {
    char muster[4][8] ={ {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},
                         {0x0A,0x0B,0x0B,0x0D,0x1E,0x2F,0x44,0x88},
                         {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},
                         {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}};

    int p,i,a=200;

    DDRD=0xff;
    PORTD=0xff;
    DDRB=0x00;

    while(1) {
        p=PINB;     // Tastenabfrage
        if (p & (1<<PB0)) i=0;
        if (p & (1<<PB1)) i=1;
        if (p & (1<<PB2)) i=2;
        if (p & (1<<PB3)) i=3;
        for (j=0; j<8; j++) {
            PORTD = muster[i][j];
            var_delay(a);
        }
    }    
}

>verbunden und den PINB 0 fest auf die 5V gelegt.Und es Passiert rein gar
>nichts auch nicht wenn man PINB 0 auf GND legt.

Weil deine Tastenabfrage falsch ist. Du musst einzelene Bits mit 
Bitmanipulation testen.

>WINAVR. Die Optimirungstufe ist auf -01 gestellt.

Wozu? Praktisch nutz man meist nur -O0 (keine Optimierung, zum Debuggen 
und Simulieren) und -Os (minimale Größe) in der realen Anwendung.

MfG
Falk

Autor: Lord_Gismo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also klar ich danke euch mit dem Beispiel von Falk funktioniert das 
super einziges Problem es ist keine Switch Case anweisung.

Ich benutze die Optimirungsstufe weil ansonsten die delay.h ein fehler 
verusacht wo drinne steht das die Optimirung eingeschaltet werden soll.

Gruß
Gismo

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lord_Gismo schrieb:
> Also klar ich danke euch mit dem Beispiel von Falk funktioniert das
> super einziges Problem es ist keine Switch Case anweisung.

So toll ist die dann auch wieder nicht :-)

Dein Problem war ja nicht der switch-case. Dein Problem war das 
Aufbereiten des Wertes, der nacheinander mit allen case-Fällen 
verglichen wurde.


Wann immer du einen Port komlpett benutzt, musst du dir Gedanken darüber 
machen, was wohl die Bits machen, die dich nicht interessieren. Wenn sie 
dich wirklich nicht interessieren, dann setzt man sie gezielt auf 0, 
damit man auf keinen Fall von irgendwelchen äusseren Einflüssen abhängig 
ist.

> Ich benutze die Optimirungsstufe weil ansonsten die delay.h ein fehler
> verusacht wo drinne steht das die Optimirung eingeschaltet werden soll.

dann nimm gleich -Os

Autor: Lord_Gismo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Von -Os wurde mir von mehrenen Personen abgeraten, da es passieren kann 
das der Compiler dann einfach nur einmal genutzte Funktionen einfach weg 
Rationalisiert.

gruß

Gismo

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lord_Gismo schrieb:

> Von -Os wurde mir von mehrenen Personen abgeraten, da es passieren kann
> das der Compiler dann einfach nur einmal genutzte Funktionen einfach weg
> Rationalisiert.

Und was ist daran falsch?

Autor: Lord_Gismo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn man die Funktion halt nur einmal braucht und sie trotzdem schreiben 
will.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ganz genau das macht die Os Optimierung, das s steht insgeheim nicht 
für small sondern für single, genau diese Funktionen werden entfernt...

Jetzt mal im Ernst, glaubst du da wirklich dran?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das macht es aber immer noch nicht falsch :-)

Es sei denn du willst im Debugger duchsteppen. Aber dann ist Optimieren 
immer problematisch.

Autor: Lord_Gismo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ja, ganz genau das macht die Os Optimierung, das s steht insgeheim nicht
>für small sondern für single, genau diese Funktionen werden entfernt...

>Jetzt mal im Ernst, glaubst du da wirklich dran?

Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt 
erzählt worden das genau das passiert ist und somit das Programm nicht 
lief.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Lord_Gismo (Gast)

>Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt
>erzählt worden

Nicht nur dort wird viel Unsinn erzählt . . . ;-)

> das genau das passiert ist und somit das Programm nicht lief.

Zu 99,9% liegt das Problem vor der Tastatur.

MFG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lord_Gismo schrieb:

> Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt
> erzählt worden das genau das passiert ist und somit das Programm nicht
> lief.

Das kann nur passieren, wenn der Compiler fehlerhaft ist oder wenn es 
sonst irgendeinen Grund gibt, warum bestimmter Code unbedingt in Form 
einer Funktion vorliegen muss.
Aber ansonsten kannst du nicht unterschieden ob die Funktion erhalten 
blieb, oder ob der Compiler sie aufgelöst hat. D.h. man kann es schon in 
einem gewissen Sinne unterscheiden: die 2te Variante läuft meistens 
etwas schneller :-)

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lord_Gismo schrieb:
>>Ja, ganz genau das macht die Os Optimierung, das s steht insgeheim nicht
>>für small sondern für single, genau diese Funktionen werden entfernt...
>
>>Jetzt mal im Ernst, glaubst du da wirklich dran?
>
> Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt
> erzählt worden das genau das passiert ist und somit das Programm nicht
> lief.

Das Problem dürfte gewesen sein, das der Erzähler beim Debuggen nicht 
verstanden hat warum seine tolle Funktion auf einmal weg war und hat die 
Schuld bei der Compileroptimierung gesucht.
Es werden aber nur Sachen wegoptimiert deren Lösungen vorhersehbar oder 
für den weiteren Ablauf nicht gebraucht werden, in diesem Fall wird aber 
die entsprechende richtige Lösung vorher eingesetzt.
Bei der Ausführung merkst du davon nichts, bis auf eventuell etwas 
weniger Speicherbedarf und/oder Geschwindigkeit.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und es gibt durchaus auch eigene Fehler, die erst bei eingeschalteter 
Optimierung auffallen (vergessenes volatile ist da wahrscheinlich der
Spitzenreiter).

Insofern ist die Geschichte nicht unglaubwürdig, nur die
Schlußfolgerung daraus ist falsch ("keine Optimierung einschalten,
weil dann meine Fehler auffallen").

Autor: Andreas Schweigstill (Firma: Schweigstill IT) (schweigstill) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lord_Gismo schrieb:
> Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt
> erzählt worden das genau das passiert ist und somit das Programm nicht
> lief.

Naja, viele (nicht alle!) Berufsschullehrer befinden sich eher am 
alleruntersten Ende der Fahnenstange, was die Fachkenntnisse, sogar in 
ihren eigenen Unterrichtsfächern, angeht.

Wenn es einen Seiteneffekt durch das Einschalten der Optimierung gab, 
dann lag er mit sehr hoher Wahrscheinlichkeit an einem 
Programmierfehler. Der Klassiker "vergessenes volatile" wurde ja schon 
erwähnt.

Wird eine Funktion als Interrupthandler eingesetzt und die entsprechende 
Adresslage nur im Linker-File angegeben, stellen Compiler und Linker 
auch nur fest, dass es keinen Bezug (Aufruf oder Definition eines 
Funktionszeigers) darauf gibt und optimieren die Funktion weg. Daher 
sollte man für solche Funktionen ggf. den Weg wählen, wie er solche 
Anwendungen dokumentiert ist, z.B. beim AVR-GCC bzw. WinAVR mit ISR() 
arbeiten.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schweigstill schrieb:
> Lord_Gismo schrieb:
>> Ich sage nicht das es so ist nur in meiner Berufsschulklasse ist es halt
>> erzählt worden das genau das passiert ist und somit das Programm nicht
>> lief.
>
> Naja, viele (nicht alle!) Berufsschullehrer ...

Muß ja nicht mal vom Lehrer erzählt worden sein.

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.