Forum: Mikrocontroller und Digitale Elektronik Pin Zustand Abfrage klappt nicht


von Andreas B. (noidea)


Lesenswert?

Hallo Zusammen,

ich versuche zu Verstehen, warum mein Programm nicht funbktioniert.
Ich möchte den Eingangszustand von PINB3 in eine Variable abspeichern 
und diese dann als if-Abrage nutzen.Dafür nutze ich einen Atmega8.

Jedoch denkt das Programm gar nicht darüber nach, das zu tun was ich 
gerne möchte. Hier mein Programm:
1
#include <avr/io.h>
2
#define F_CPU 1200000
3
#include <util/delay.h>
4
5
6
int main(void)
7
{
8
    
9
DDRB= (1<<0);                   //PB0 als Ausgang
10
DDRB &=~(1<<3);      //PB3 als Eingang
11
PORTB &=~(1<<3);    //PullUp PB3 deaktivieren
12
PORTB &=~ (1<<0);    //PB0 auf Low setzen
13
  
14
int state = 0;
15
int laststate = 0;
16
  
17
    while (1) 
18
    {
19
  //state = (PORTB & (1<<3)) == (1<<3);
20
  state = PINB & (1<<3);           //Eingang in state schieben
21
    
22
    if (laststate==0 && state==1)
23
    {
24
      PORTB |= (1<<0);    //Auf High setzen
25
    }
26
    else
27
    {
28
      PORTB &=~ (1<<0);    //Auf Low setzen
29
    }
30
    }
31
}

Könnte mir bitte jemand, auch gerne unsanft :-) , erklären wo ich den 
Fehler gemacht habe? Das ist bestimmt wieder was richtig blödes.

Vielen Dank und schöne Grüße

von dummschwaetzer (Gast)


Lesenswert?

>state = PINB & (1<<3);
ist dann zwar größer null aber niemals 1

von Andreas B. (bitverdreher)


Lesenswert?

Das Resultat ist hier:
  state = PINB & (1<<3);           //Eingang in state schieben
8 bei gesetztem Bit
Hier:
    if (laststate==0 && state==1)
Fragst Du auf 1 ab.

von dummschwaetzer (Gast)


Lesenswert?

hinweis2:
state ist entweder 0 oder (1<<3), könnte man aber auch als 0x08 
schreiben.

von Falk B. (falk)


Lesenswert?

Andreas B. schrieb:
>   state = PINB & (1<<3);           //Eingang in state schieben

Das ist eine Bitmanipulation, so weit, so gut, aber

>
>     if (laststate==0 && state==1)

Falsch! Dein Bit steckt in bit #3! Das hat die Wertigkeit 8! Dein state 
wird also NIE 1 sein, sondern nur 0 oder 8!

Es gibt mehrere Lösungen.

Logische Abfrage auf true und false statt binärer Abfrage.

if (laststate == false && state == true)  // lange Schreibweise
if (!laststate && state)  // Kurzschreibweise

Damit wird geprüft, ob die Variablen Null (== false) oder ungleich Null 
(==true) sind. Damit ist es egal, wo das Bit in der Variable gesetzt 
ist. Das ist praktisch die meist verbreitete Löösung, wenn gleich die 
nicht 100% sauber ist (Mischung von boolscher Auswertung mit Integer)

Richtig sauber wäre

bool state = 0;
bool laststate = 0;

Man kann auch bei den Integervariabeln bleiben und wie folgt korrekt 
auswerten, aber das macht kaum einer, weil es zuviel Schreibarbeit ist 
und auch aufwändiger zu lesen ist.

if ( ((laststate & (1<<3)) == 0) &&
     ((state & (1<<3))     == 1)

: Bearbeitet durch User
von Andreas B. (noidea)


Lesenswert?

Ja jetzt wo ihr es schreibt ist es klar das da 8 drin steht und nicht 
die 1 (also High) wie von mir gewünscht.

Aber wie kann ich dann den Zustand von PINB3, also 0 oder 1, in state 
schreiben?

von Einer K. (Gast)


Lesenswert?

Andreas B. schrieb:
> Aber wie kann ich dann den Zustand von PINB3, also 0 oder 1, in state
> schreiben?

Alles gut.
Einfach die Auswertung ändern.

Z.B. so:
Andreas B. schrieb:
> if (laststate==0 && state==1)
Ersetzen durch:
if (state && not laststate)

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Das hier ginge auch noch:
1
if (!!laststate==0 && !!state==1)

oder einfach
1
if (!laststate && state)

: Bearbeitet durch User
von Assemblererer (Gast)


Lesenswert?

Nebenbemerkung:

Seitdem ich C mache leide ich daran dass es "gefühlt" (ja, nur
gefühlt) nicht sicher ist dass ein Wert ungleich Null bei der
Auswertung eines Boolschen Ausdrucks ein True ergibt. Also
Typkonvertierung von int nach bool ist für mich eine dunkle
Grauzone, auch wenn es irgendwo in den Abgründen von C
definiert ist (sein soll, hab ich mir von meinem kompetenten
Kollegen sagen lassen).

Bitte erschlagt micht nicht ob meiner Bedenken, aber issso.

Deswegen schreibe ich immer für true "!=0" oder false "==0".

Vielleicht gab es sogar in den Anfängen von C diese
Undefiniertheit?

von Einer K. (Gast)


Lesenswert?

Assemblererer schrieb:
> Vielleicht gab es sogar in den Anfängen von C diese
> Undefiniertheit?
Eigentlich nicht.

Es gab "damals" nur nicht den expliziten/verwendbaren Datentype bool.

Ansonsten sind die Regeln, für die impliziten Konvertierungen, klar und 
deutlich ausformuliert und haben sich auch die letzten zig Jahre nicht 
geändert.

von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Falk B. schrieb:
> if (laststate == false && state == true)  // lange Schreibweise

Die prüfung auf true kann aber auch in die Hose gehen wenn state nicht 
explizit als bool deklariert ist. Etliche Compiler nehmen für true in 
dem Fall "#define true 1" und somit passt es nicht wenn state z.B. ein 
"int" ist.

"state != false" ist dagegen Sicher weil false immer als "Null" 
definiert ist.
Auf "irgendwas == true" zu prüfen sollte man sich garnicht erst 
angewöhnen.

von Falk B. (falk)


Lesenswert?

Irgend W. schrieb:
> Etliche Compiler nehmen für true in
> dem Fall "#define true 1" und somit passt es nicht wenn state z.B. ein
> "int" ist.

Das glaube ich nicht, das machen bestenfalls ein paar Amateure, die C 
nicht verstanden haben.

von Assemblererer (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ansonsten sind die Regeln, für die impliziten Konvertierungen, klar und
> deutlich ausformuliert

Das habe ich in keiner Weise bezweifelnd angesprochen.

Du hast schon meinen Satz der den Token "gefühlt" beinhaltet,
gelesen, zur Kenntnis genommen?

von Einer K. (Gast)


Lesenswert?

Assemblererer schrieb:
> Du hast schon meinen Satz der den Token "gefühlt" beinhaltet,
> gelesen, zur Kenntnis genommen?

Klar!
Nur: Ich bin nicht für deine Gefühle verantwortlich!
Denn sie entstehen in dir.

Zudem stört es mich ein wenig, dieses konkreten Gefühl/Angst auf andere 
zu projizieren. Darum werde ich dich darin nicht unterstützen, sondern 
dagegen agieren.

von Andreas B. (noidea)


Lesenswert?

Ihr seid klasse. Vielen Dank für Eure Unterstützung. Mit Anpassen
der Abfrage hat es jetzt auch geklappt.

Ich habe jetzt auch verstanden warum das so vorher nicht geklappt hat, 
was ja irgendwie auch logisch war.

Auf jeden Fall noch einmal vielen Dank für Eure Hilfe und bleibt Gesund 
:-)

Viele Grüße und einen schönen Sonntag

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.