Forum: Mikrocontroller und Digitale Elektronik If-Phaenomen


von If-Phaenomen (Gast)


Lesenswert?

Ich habe folgends Problem bei einer If-Abrage.
Aus irgendwelchen mir noch nicht bekannten Gründen überspringt das 
Programm immer die zweite if-Abfrage.

if (Pinabfrage & 0x02) ... wird überhaupt nicht genommen, im Debug-Modus 
hüpft das AVR-Studio sofort von der ersten Abfrage zur Dritten Abfrage - 
warum, dass ist mir ein Rätsel. Weis von Euch vlt. jemand eine Antwort 
darauf?

1
int main(void)
2
{
3
  // eigene Variablen
4
  uint8_t Pinabfrage;
5
  
6
  // Baudrate einstellen und BITS in UBBR setzen
7
  // uart_init (UART_BAUD_SELECT (UART_BAUD_RATE, F_CPU));
8
  
9
  // Datenrichtung festsetzen
10
  DDRB = 0x00;  // alles Eingänge
11
  
12
  // Interrupts einschalten
13
  sei ();
14
    
15
  while (1)
16
  {
17
    Pinabfrage = PINB;
18
    
19
    if (Pinabfrage & 0x01) 
20
    {
21
      Schalter1();
22
    }
23
    
24
    if (Pinabfrage & 0x02)
25
    {
26
      Schalter2();
27
    }
28
    
29
    /* if (PINB & 0x02)
30
    {
31
      Schalter2();
32
    } */
33
    
34
    if (Pinabfrage & 0x03)
35
    {
36
      Schalter3();
37
    }
38
    
39
    if (Pinabfrage & 0x04)
40
    {
41
      Schalter4();
42
    }
43
  }
44
}

von Maddin J. (themaddin)


Lesenswert?

Guten morgen!
Schalte mal die Compiler-Optimierungen aus und probier nochmal.
Gruß Martin

von Bananen Joe (Gast)


Lesenswert?

Weil in der dritten Abfrage das gleiche nochmal abgefragt wird.
Hex:Bit-Folgen
0x01: 00000001
0x02: 00000010
0x03: 00000011
0x04: 00000100
Ich denke an jedem Portpin hængt bei dir ein Schalter, wenn dem so ist, 
solltest du fuer Schalter1 0x01, fuer Schalter2 0x02, fuer Schalter3 
0x04 und fuer Schalter4 0x08 benutzen, dann klappt es auch.
Weitere Møglichkeiten findest du hier: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports.

von Rolf Magnus (Gast)


Lesenswert?

If-Phaenomen schrieb:
> Ich habe folgends Problem bei einer If-Abrage.
> Aus irgendwelchen mir noch nicht bekannten Gründen überspringt das
> Programm immer die zweite if-Abfrage.

Also wird Schalter2() tatsächlich nicht ausgeführt, auch wenn der Wert 
eigentlich passen würde? Oder hast du nur im Debugger das (vemeintlich) 
falsche Verhalten bemerkt? Wenn Optimierungen an sind, kann es sein, daß 
das Programm umsortiert wird oder Teile zusammengefasst werden. Wenn 
z.B. Schalter2() eine leere Funktion ist, kann es auch sein, daß der 
Aufruf mitsamt der Abfrage komplett entfernt wird, da das dann am 
Verhalten des Programms nichts ändert.

von Uli T. (avaron)


Lesenswert?

Nein, da wird nichts nochmal abgefragt!
Außer dem oben angegebenen Fall das Schalter2() leer ist kann da auch 
nichts wegoptimiert werden.
Das Verhalten wie oben beschrieben ist nicht möglich!
Also entweder wird hier was umsortiert und der Code kommt später dran, 
oder aber Schalter2() ist leer.

Zeig mal den asm-output.

Nachtrag: ANsonsten hat Banana Joe natürlich Recht, Dein Programm macht 
vermutlich etwas anderes wie Du erwartest, aber möglich ist das 
beschriebene Verhalten eigentlich trotzdem so nicht! Die 2te Abfrage 
kann nicht wegoptimiert werden wenn Schalter2() Code enthält!

von Karl H. (kbuchegg)


Lesenswert?

Uli Trautenberg schrieb:

> beschriebene Verhalten eigentlich trotzdem so nicht! Die 2te Abfrage
> kann nicht wegoptimiert werden wenn Schalter2() Code enthält!

Wegoptimiert kann der Aufruf nicht werden.
Aber umsortiert.

denn 0x03 ist nicht anderes als eine Kombination von 0x01 und 0x02

In diesem Code gibt es nur 3 unterschiedliche Fälle
* es wird schalter1() UND schalter3() ausgeführt
* es wird schalter2() UND schalter3() ausgeführt
* es wird schalter4() ausgeführt.


Aber die ersten beiden Möglichkeiten sind immer so. Wenn entweder 
schalter1() oder schalter2() ausgeführt wird, dann wird auch noch ein 
schalter3() hinten nachgeschoben. Immer? Immer!

Und wenn das der Compiler gegnissen hat, dann kann es schon sein, dass 
er da den Code ein wenig umsortiert hat.



PS: Ich denke auch, dass der TO das eigentlich ganz anders haben wollte. 
Aber was er haben wollte und was er geschrieben hat sind nun mal 2 paar 
Schuhe.

von Phil P. (john_d)


Lesenswert?

Karl Heinz Buchegger schrieb:
> PS: Ich denke auch, dass der TO das eigentlich ganz anders haben wollte.
> Aber was er haben wollte und was er geschrieben hat sind nun mal 2 paar
> Schuhe.

Ich denke auch, dass klar werden muss, was das Ziel ist...
Bist du (If-Phaenomen) denn sicher, dass das Problem nur beim zweiten 
If-Block besteht? werden Nr. 3 und 4 defnitiv ausgeführt?

von Uli T. (avaron)


Lesenswert?

Naja, umsortiert werden kann es eigentlich nur zu: (C-Äquivalent)

if (Pinabfrage & 0x03) {

  if (Pinabfrage & 0x01) {
    Schalter1();
  }
  if (Pinabfrage & 0x02) {
    Schalter2();
  }

  Schalter3();
}


Alles andere würde die Aufrufreihenfolge von Schalter<n>() ändern, und 
das darf selbst der Optimizer nicht. Aber gut, könnte sein das ein 
entsprechendes Code-Konstrukt vom Debugger so mißverstanden wird das es 
sich wie oben angegeben äußert....

von Rolf Magnus (Gast)


Lesenswert?

Uli Trautenberg schrieb:
> Alles andere würde die Aufrufreihenfolge von Schalter<n>() ändern, und
> das darf selbst der Optimizer nicht.

Wenn er den Inhalt der Funktionen kennt und auswertet, wie es beim 
Inlining z.B der Fall wäre, und er erkennt, daß eine Änderung der 
Reihenfolge keine Auswirkung auf die Funktionalität hat, kann er auch 
das tun.

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.