Forum: Mikrocontroller und Digitale Elektronik ATMEGA 168PA 2 PINS abfragen


von Tobias x. (dertobias)


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

von Uwe (de0508)


Lesenswert?

Hallo,

es gibt logisches UND und OR und Bitweises UND und OR, das verwendest Du 
nicht richtig.

Zur welcher Kathegorie gehört: & und | ?

von Tobias x. (dertobias)


Lesenswert?

zur Bitweisen. müssten die gehören.

Aber auch logisches && funktioniert nicht.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

Tobias xxx schrieb:
> zur Bitweisen. müssten die gehören.
>
> Aber auch logisches && funktioniert nicht.

Deine Klammerungen sind richtig?

von Tobias x. (dertobias)


Lesenswert?

Bei den klammerungen hab ich wohl nen fehler drinn gehabt, aber trotzdem 
funktioniert es nicht.

von Peter D. (peda)


Lesenswert?

Tobias xxx schrieb:
> Wieso funktioniert dieses hier nicht ?

Vermutlich, weil Du es nochmal geschrieben hast statt copy&paste.
D.h. Dein getesteter Code ist anders.

Und benutze die Formatierung:
Antwort schreiben
Wichtige Regeln - erst lesen, dann posten!

Oder den Dateianhang.


Peter

von Tobias x. (dertobias)


Lesenswert?

Wieso ist mein getesteter Code anders? habe doch nur aus dem | ein & 
gemacht.

von Peter D. (peda)


Lesenswert?

Tobias xxx schrieb:
> Wieso ist mein getesteter Code anders?

Weil Dein geposteter Code funktioniert.

Und weil das immer passiert bei Nichtbenutzung von copy&paste.
Der Mensch ist ein schlechter Kopierer.


Peter

von Tobias x. (dertobias)


Lesenswert?

Also ich habe jetzt nochmal copy&paste genutzt und nur die pin nnummern 
und den Operator geändert. es funktioniert trotzdem noch nicht. denn, 
wenn beide 0 oder 1 sind, soll er mit der while schleife aufhören. nur 
wenn pin1 0 ist und pin0 1 ist soll er weitermachen.

von Karl H. (kbuchegg)


Lesenswert?

Würdest du jetzt BITTE mal deinen richtigen Code posten? So wie er jetzt 
aussieht nachdem du die bisher angemerkten Dinge korrigiert hast. Und 
zwar nach Möglichkeit alles?


Vielen Dank, dass du uns gnädigerweise in die Lage versetzt, dir zu 
helfen.

von Tobias x. (dertobias)


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

von Peter D. (peda)


Lesenswert?

Tobias xxx schrieb:
> if (( !PINB & ( 1 << PINB0) ) && ( PINB & ( 1 << PINB1) ))

Falsch!
1
///Entweder:
2
if (( !(PINB & ( 1 << PINB0)) ) && ( PINB & ( 1 << PINB1) ))
3
//Oder:
4
if (( ~PINB & ( 1 << PINB0) ) && ( PINB & ( 1 << PINB1) ))

Peter

von Tobias x. (dertobias)


Lesenswert?

JA Super! Jetzt klappt es. Vielen lieben Dank.
Diese dumme tide hätte gereicht oder halt die klammern besser setzen.

Dankeschön

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.