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
intmain(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
intstate=0;
15
intlaststate=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
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)
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?
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)
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?
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.
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.
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.
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?
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.
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
Eine eigene Frage?
Dieser Thread ist über 5 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.