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


von Lord_Gismo (Gast)


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

von Klaus W. (mfgkw)


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?

von Klaus W. (mfgkw)


Lesenswert?

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

von Falk B. (falk)


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

von Lord_Gismo (Gast)


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

von Karl H. (kbuchegg)


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

von Lord_Gismo (Gast)


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

von (prx) A. K. (prx)


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?

von Lord_Gismo (Gast)


Lesenswert?

Wenn man die Funktion halt nur einmal braucht und sie trotzdem schreiben 
will.

von Tim T. (tim_taylor) Benutzerseite


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?

von Karl H. (kbuchegg)


Lesenswert?

Das macht es aber immer noch nicht falsch :-)

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

von Lord_Gismo (Gast)


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.

von Falk B. (falk)


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

von Karl H. (kbuchegg)


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 :-)

von Tim T. (tim_taylor) Benutzerseite


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.

von Klaus W. (mfgkw)


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").

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


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.

von Klaus W. (mfgkw)


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.

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.