Probleme mit der Case switch anweisung

Gast #1735366
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.
1
int main (void)
2

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

8

9
DDRD=0xff;
10
PORTD=0xff;
11
DDRB=0x00;
12
  while(1)
13
  {
14
  p=PINB;
15
    switch(p)
16
    {
17
    case 0x00:
18
  
19
      for(i=0;i<=7;i++)
20
        {
21
        PORTD=out1[i];
22
        _delay_ms(a);
23
        }
24
  
25
      for(i=7;i>=0;i--)
26
        {
27
        PORTD=out1[i];
28
        _delay_ms(a);
29
        }
30
    break;
31

32
    case 0x01:
33
      for(i=0;i<=7;i++)
34
        {
35
        PORTD=out2[i];
36
        _delay_ms(a);
37
        }
38
  
39
      for(i=7;i>=0;i--)
40
        {
41
        PORTD=out2[i];
42
        _delay_ms(a);
43
        }
44
    break;
45
    }  
46
  }
47
return(0);
48
}

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
#1735378
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-Tutorial#Warteschleifen_.28delay.h.29

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

10
    int p,i,a=200;
11

12
    DDRD=0xff;
13
    PORTD=0xff;
14
    DDRB=0x00;
15

16
    while(1) {
17
        p=PINB;     // Tastenabfrage
18
        if (p & (1<<PB0)) i=0;
19
        if (p & (1<<PB1)) i=1;
20
        if (p & (1<<PB2)) i=2;
21
        if (p & (1<<PB3)) i=3;
22
        for (j=0; j<8; j++) {
23
            PORTD = muster[i][j];
24
            var_delay(a);
25
        }
26
    }    
27
}

>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
Gast #1735455
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
#1735456
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
Gast #1735517
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.
#1735524
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
#1735526
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 :-)
Gast #1735550
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.
#1735678
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").
(Firma: Schweigstill IT) Persönliche Seite #1736226
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren