ATMEGA 168PA 2 PINS abfragen

OP #2574907
Lesenswert?

HAllo Leute,

eine Frage:

if ((PINB & (1 << PINB6)) == 0 | ((PINB & (1 << PINB7)) == 0 ))    diese 
Abfrage funktioniert ohne probleme.

Wieso funktioniert dieses hier nicht ?

while((PINB & (1 << PINB1)) == 0 & ((PINB & (1 << PINB0)) == 1))

Hier soll solange weitergemacht werden, solange PINB1 0 ist und PINB0 1

Nur irgendwie funktioniert das nicht. Muss ich da irgendwas anders 
machen ?

LG Tobias
#2574931
Lesenswert?

Zusätzlich

gewöhn dir diese Vergleiche mit 0 und 1 wieder ab. Das sind potentielle 
Fallen.

Das hier:

(PINB & (1 << PINB0)) == 1)

funktioniert nur deswegen zufällig, weil du Pin 0 abfrägst. Mit anderen 
Pins würde das nicht gehen, weil bei der Maskierung eines Bits dann eben 
nicht 1 rauskommt.


C hat die Konvention, dass ein Wert von 0 als logisch falsch gewertet 
wird und jeder andere Wert ist logisch wahr.
Das kannst du hier zu deinem Vorteil ausnutzen


   if( PINB & ( 1 << PINB0) )
   {
      ...

geht dann in den abhängigen Teil rein, wenn der Pin auf 1 ist. Egal 
welcher Pin. Denn nach dem ausmaskieren des Bits bleibt ein Wert übrig, 
der entweder 0 oder ungleich 0 ist. Welcher Wert es im letzten Fall 
genau ist, hängt von der Pinnummer (der Bitnummer) ab. Aber dich 
interessiert ja die genaue Zahl nicht, du willst nur wissen, ob da etwas 
ungleich 0 rauskommt.

Die Umkehrung: Abfrage ob der Pin nicht gesetzt ist

   if( !(PINB & ( 1 << PINB0) ) )
   {
      ....

Das ! ist ein logisches NICHT und dreht die Auswertung um. Wenn also der 
Pin NICHT gesetzt ist, dann ....


In C ist manchmal weniger mehr. Das hier ist so ein Fall. Mit expliziten 
Vergleichen auf 0 bzw. 1 ist die Gefahr sehr groß, dass du dir selber 
ins Knie schiesst.
OP #2575051
Lesenswert?

1
int rechtslauf(void)
2
{
3
      PORTD |= arrow_segments[0]; //a0b00000001;
4
      //_delay_ms(200); 
5
      PORTD |= arrow_segments[1]; //0b00000010;
6
      //_delay_ms(200);
7
      PORTD |= arrow_segments[2]; //0b00000100;
8
      //_delay_ms(200); 
9
      PORTD |= arrow_segments[3]; //0b00011000;
10
      //_delay_ms(200);
11
      PORTD &= ~arrow_segments[0]; //~0b00000001;
12
      //_delay_ms(200);
13
      PORTD &= ~arrow_segments[1]; //~0b00000010;
14
      //_delay_ms(200);
15
      PORTD &= ~arrow_segments[2]; //~0b00000100;
16
      //_delay_ms(200);
17
      PORTD &= ~arrow_segments[3]; //~0b00011000;
18
      //_delay_ms(200);
19
      if ((PINB & (1 << PINB6)) == 0 | ((PINB & (1 << PINB7)) == 0 ))    //Ein Betriebsartenpin auf 0 gezogen?
20
        {
21
        //_delay_ms(50);
22
        return;
23
        }        
24
      if (( !PINB & ( 1 << PINB0) ) && ( PINB & ( 1 << PINB1) ))          
25
      {
26
        rechtslauf();
27
      }
28
      else
29
      {
30
      return;
31
      }
32
}

Ich habe es jetzt mal für meine letzte if bedingung die ja nicht 
funktioniert so gemacht wie du gesagt hast, das ich nicht direkt auf 1 
oer 0 abfrage. Er soll wenn PIN1 gesetzt ist und PIN0 nicht gesetzt ist 
wieder in den rechtslauf springen ansonsten aus dem UP aussteigen.
Es klappt so wie ich es jetzt habe weder mit dem & noch mit dem &&
Hoffe es wird jetzt klarer.

Vielen Dank

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