Forum: Mikrocontroller und Digitale Elektronik C: Jumperabfrage geht nicht (AVR M8)


von W_Horm (Gast)


Lesenswert?

Hallo,
ich möchte an Pin D3 eine Jumperabfrage machen (ob Jumper vom Pin gegen 
Masse gesetzt ist oder nicht).


Folgendes soll passiern:

Jumper gesetzt = Pin auf LO: Funktionsaufruf "eins()"

Jumper nicht gesetzt = Pin auf HI: Funktionsaufruf "zwei()"


Hier der Code:
1
// Port D auf Eingang + Pullups aktiv
2
DDRD = 0x00;
3
PORTD = 0xff;
4
5
while(1)  // Endlosschleife
6
{
7
8
d = PIND; // Portabfrage Port D
9
10
    if (( d & (1 << PIND3)) == 0)
11
    {
12
    eins();
13
    }
14
15
16
    if (( d & (1 << PIND3)) == 1)
17
    {
18
    zwei();
19
    }
20
21
}


Leider funktioniert es nicht.

"if (( d & (1 << PIND3)) == 0)" geht,
aber bei
1
if (( d & (1 << PIND3)) == 1)
 muss irgendwo ein Fehler sein.


Meine Idee war:
0 & 1 = 0 , => JMP gegen Masse
1 & 1 = 1 , => JMP auf Hi


Wo liegt der Fehler?

von Petrov (Gast)


Lesenswert?

if (( d & (1 << PIND3)) == 0)
    {
    eins();
    }else{
     zwei();
    }

dann gehts

oder

if (( d & (1 << PIND3)) == 8) weil 2^3=8 und nicht 1
    {
    zwei();
    }

gruß peter

von W_Horm (Gast)


Lesenswert?

noch mal analytisch betrachtet:
1
if (( d & (1 << PIND3)) == 0)

bedeutet ja:

7 6 5 4 3 2 1 0 (Bitnummer)
1 1 1 1 0 1 1 1 (Inhalt PIND wenn PinD3 auf Masse)
        1       (vierfache Links-Shift einer "1")
===============
        0       (Ergebnis der AND-Verknüpfung)

von W_Horm (Gast)


Lesenswert?

Petrov schrieb:
> if (( d & (1 << PIND3)) == 8) weil 2^3=8 und nicht 1
>     {
>     zwei();
>     }

Danke Peter! Jetzt fallen bei mir die Groschen nach!

ELSE hatte ich auch schon überlegt, wollte aber unbedingt den logischen 
Fehler finden.

Noch mal Danke!!!

von Krapao (Gast)


Lesenswert?

1
/*
2
  An Pin D3 eine Jumperabfrage machen 
3
  (ob Jumper vom Pin gegen Masse gesetzt ist oder nicht).
4
  Folgendes soll passiern:
5
  Jumper gesetzt = Pin auf LO: Funktionsaufruf "eins()"
6
  Jumper nicht gesetzt = Pin auf HI: Funktionsaufruf "zwei()"
7
*/
8
#include <avr/io.h>
9
10
void eins(void)
11
{
12
}
13
14
void zwei(void)
15
{
16
}
17
18
int main(void)
19
{
20
  // Port D auf Eingang + Pullups aktiv
21
  DDRD = 0x00;
22
  PORTD = (1<<PIND3);
23
24
  while(1) 
25
  {
26
    uint8_t d = PIND;
27
28
    if (( d & (1 << PIND3)) == 0)
29
    {
30
    eins();
31
    }
32
33
    if (( d & (1<<PIND3)) == (1<<PIND3))
34
    {
35
    zwei();
36
    }
37
  }
38
}

von Petrov (Gast)


Lesenswert?

7 6 5 4 3 2 1 0 (Bitnummer)
1 1 1 1 0 1 1 1 (Inhalt PIND wenn PinD3 auf Masse)
0 0 0 0 1 0 0 0 (vierfache Links-Shift einer "1")
===============
0 0 0 0 0 0 0 0 (Ergebnis der AND-Verknüpfung)


oder

7 6 5 4 3 2 1 0 (Bitnummer)
1 1 1 1 1 1 1 1 (Inhalt PIND wenn PinD3 auf Masse)
0 0 0 0 1 0 0 0 (vierfache Links-Shift einer "1")
===============
0 0 0 0 1 0 0 0 (Ergebnis der AND-Verknüpfung)

Gruß peter

von Mat (Gast)


Lesenswert?

oder einfach:
1
    if (!( d & (1 << PIND3)))
2
    {
3
       // Wenn IF Bedingung gleich 0
4
       eins();
5
    }
6
7
    if ( d & (1<<PIND3))
8
    {
9
       // Wenn IF Bedingung ungleich 0
10
       zwei();
11
    }

Eine IF Bedingung gibt FALSE wenn das Argument gleich 0 ist und TRUE 
wenn das Argument UNGLEICH 0 ist.
Ein Rufezeichen '!' dreht das ganze um.

gruß Mat

von W_Horm (Gast)


Lesenswert?

Danke für die Hinweise und Anregungen!


Habe noch eine andere Frage zur While-Schleife.
1
volatile uint8_t p = 0;
2
3
while ( p = 0 )
4
{
5
  c = PINC; // Portabfrage Port C
6
7
    if (( c & (1 << PINC3)) == 0)
8
    {
9
    p = 1; // wenn PinC3 auf Masse, dann p != 0 und While-Schleife wird verlassen
10
    }
11
}

Der Compiler meckert an:

"warning: suggest parentheses arround assignment used as truth value"

und

es funktioniert nach dem Compilieren auch nicht, die Schleife läuft 
trotz Tastendruck an PinC3 endlos weiter.


Ich verstehe bloß nicht, warum...

von Krapao (Gast)


Lesenswert?

assignment ist auf Deutsch Zuweisung.

Willst du wirklich bei der Bedingung der While-Schleife eine Zuweisung 
machen, so wie du es hin geschrieben hast?

von Volker G. (voga2073)


Lesenswert?

Sollte heißen:
1
while ( p == 0 )

von W_Horm (Gast)


Lesenswert?

Krapao schrieb:
> Willst du wirklich bei der Bedingung der While-Schleife eine Zuweisung
> machen, so wie du es hin geschrieben hast?

Also, solange p = 0 läuft die Schleife endlos durch.
Wenn die IF-Abfrage wahr, dann p = 1 und die Schleife wird verlassen.
So möchte ich es zumindest haben.

Verstehe nicht das Problem, scheint mir wie oben geschrieben logisch.

von W_Horm (Gast)


Lesenswert?

Volker G. schrieb:
> while ( p == 0 )

Ach, Mist, Danke! Geht ja um eine Bedingung!
;O)

von Karl H. (kbuchegg)


Lesenswert?

oder noch einfacher
1
while ( !p )


@W_Horm
Du merkst schon: In C ist manchmal weniger einfach mehr.

Bei
1
  if( w )
2
  {
3
    ...
4
  }
5
  else
6
  {
7
    ...
8
  }

gibt es kaum Möglichkeiten für Tippfehler in den Bedingungen. Bist du 
aber explizit
1
  if( w != 0 )
2
  {
3
    ...
4
  }
5
  if( w == 0 )
6
  {
7
    ...
8
  }

hast du jede Menge Potential für Tippfehler oder sonstige Möglichkeiten 
für fehlerhafte Abfragen. Die erste Version (die mit dem else) betont 
augenscheinlich, dass der erste Codeabschnitt und der zweite 
Codeabschnitt nur von einer einzigen Bedingung abhängen. Die zweite 
Variante ist da nicht so offensichtlich. ALs Leser muss ich mich erst 
einmal davon überzeugen, dass die eine Bedingung tatsächlich das genaue 
Gegenteil von der anderen ist. Bei einem else brauch ich das nicht tun, 
das else impliziert das ganz von alleine.

Und das andere: C erlaubt dir ausdrücklich die Verwendung der Regel: 0 
wird als logisch FALSE gewertet und alles andere ist automatisch logisch 
TRUE. Diese Regelung erlaubt dir, Bedingungen so zu formulieren, dass du 
Vergleiche auf Gleichheit bzw Ungleichheit ganz ohne Vergleichsoperation 
formulieren kannst. Und damit auch ohne die beliebte Anfängerfalle, dass 
ein einzelnes = eine Zuweisung und kein Vergleich ist.

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.