C: Jumperabfrage geht nicht (AVR M8)

Gast #2367974
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?
Gast #2367983
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)
Gast #2367985
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
}
Gast #2367986
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
Gast #2368002
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
Gast #2368042
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...
Gast #2368070
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.
#2368075
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.

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