Hallo erstmal!
Ich quäle mich jetzt schon einige Zeit mit dem Problem, dass ich den
Zustand von PIND2 als Bit in eine Variable speichern möchte.
Die einzige Lösung, die ich gefunden habe, womit ich wirklich den
Zustand des Bits PIND2 abfragen kann ist: "if(PIND&(1<<PIND2))"
Ich habe ein Bitfeld angelegt und wollte nur den Zustand von PIND2
abspeichern und dann mittels dieser Variable einen Ausgangspin setzen.
Leider funktioniert das nicht. Ich kann nur den ganzen Port D einlesen
und dann entsprechend der Wertigkeit des PIND2 den Zustand abfragen.
In der Beschreibung steht aber, dass eben "PINx.n" dazu verwendet werden
kann, den Zustand eines Eingangpins abzufragen.
Vielleicht habe ich ja nur ein Verständnisproblem - jedenfalls wäre es
nett, wenn mir jemand das erklären könnte.
Ich kenne mich leider nur mit PIC's aus. Beim CC5X Compiler geht es
wirklich mit z.B. PORTA.2 (3. Pin von Port A).
Geht das bei Atmels nicht mit z.B. PA2 ??
Alex Bürgel wrote:
> Ich kenne mich leider nur mit PIC's aus. Beim CC5X Compiler geht es> wirklich mit z.B. PORTA.2 (3. Pin von Port A).> Geht das bei Atmels nicht mit z.B. PA2 ??
Nein, das geht beim WINAVR-Compiler nicht (und ist auch nicht ANSI-C).
Was aber gehen könnte, ist
Ich beziehe mich mit meiner Frage auf das AVR-GCC Tutorial von dieser
Homepage. Bei der Beschreibung über die Ports wird ja erklärt, dass man
zuerst mal die Datenrichtung festlegt usw.
Außerdem lässt sich ja eine Abfrage mit dem Eintrag "PIND2" (für meinen
Versuch) durchführen - eben nur in dieser Weise: "if(PIND&(1<<PIND2))"
Möchte ich jedoch den Zustand von "PIND2" in eine Variable speichern
(z.B.: x.pin = PIND2), welche ich auch noch als Bitvariable definiert
habe, und danach "x.pin" in Verzweigungen abfrage, geht das nicht.
ich vermute das du sowas vorhast:
Bits.Bit0 = PIND&(1<<PD2);
Das funktioniert nicht weil die Bit Variable nur auf das 2^0 Bit
reagiert, du musst also das Bit nach rechts shiften.
das sollte funktionieren:
Bits.Bit0 = (PIND&(1<<PD2))>>PD2;
EDIT:
Wenn ich mich recht erinnere ist ein if(PIND&(1<<PD2))/else einen Tick
schneller/kleiner als die shifterei.
Also danke erstmal für die schnellen Antworten - deshalb finde ich
dieses Forum/diese Homepage auch so gut (Lob muß auch mal sein).
Prinzipiell kann ich ja den Zustand abfragen - ich wollte / möchte
eigentlich nur wissen, warum ich den Zustand des Bit "PIND2" im Register
"PIND" nicht direkt in eine Bitvariable abspeichern und dann wie folgt
verarbeiten kann:
"struct{
x.pin:1;
}x;
....
....
x.pin = PIND2;
if(x.pin==0)
tu dies;
if(x.pin ==1)
tu das
> warum ich den Zustand des Bit "PIND2" im Register> "PIND"
Sagte ich doch schon. Die kleinste Einheit ist nun
mal ein Byte. Das Register PIND kann nur als ein
komplettes Byte ausgelesen werden.
Natürlich steht es einem frei, mittels UND und ODER
Operationen irgendwelche Maskieroperationen anzubringen,
aber tief im innersten arbeitet ein µC (zumindest ein
AVR) immer mit ganzen Bytes (abgesehen von ein paar
Spezialbefehlen die tatsächlich auf nur 1 Bit in einem
Byte operieren, wie zb sei)
F. Kriewitz wrote:
> EDIT:> Wenn ich mich recht erinnere ist ein if(PIND&(1<<PD2))/else einen Tick> schneller/kleiner als die shifterei.
Wenn der Compiler schlau ist, dann macht er aus dem if(PIND & (1 <<
PIND2)) eine sbis-Intruktion. Schneller und kürzer geht es vermutlich
gar nicht. Es sieht nur u.U. im C-Code ein bisschen sperrig aus.
Allerdings habe ich Zweifel, dass der Compiler das tatsächlich macht...
Ich versuchs nochmal:
PIND&(1<<PD2)
ergibt z.B.:
0b00000100
Für if ist das true (da != 0)
Bitvariable interessieren sich aber nur für das ersten (2^0, etc.)
Bit(s).
0bXXXXXXX1
Die anderen Bits werden praktisch ignoriert.
F. Kriewitz wrote:
> Ich versuchs nochmal:>> PIND&(1<<PD2)> ergibt z.B.:> 0b00000100> Für if ist das true (da != 0)>> Bitvariable interessieren sich aber nur für das erste (2^0) Bit.> 0bXXXXXXX1> Die anderen Bits werden praktisch ignoriert.
Hast Du das gesehen, was ich oben geschrieben habe? Wenn man den
Compiler zwingt, das "PIND & (1 << PIND2)" als Wahrheitswert zu nehmen,
ist sämtliche Schieberei überflüssig!
Johannes M. wrote:
> Hast Du das gesehen, was ich oben geschrieben habe? Wenn man den> Compiler zwingt, das "PIND & (1 << PIND2)" als Wahrheitswert zu nehmen,> ist sämtliche Schieberei überflüssig!
Klar, habe ich ja oben auch schon geschrieben das ein if die bessere
Lösung ist.
F. Kriewitz wrote:
> Johannes M. wrote:>> Hast Du das gesehen, was ich oben geschrieben habe? Wenn man den>> Compiler zwingt, das "PIND & (1 << PIND2)" als Wahrheitswert zu nehmen,>> ist sämtliche Schieberei überflüssig!> Klar, habe ich ja oben auch schon geschrieben das ein if die bessere> Lösung ist.
Ich rede nicht von dem if sondern von meinem Posting um 10:00 Uhr! Das
mit dem if geht wie gesagt nur theoretisch. Der Compiler ist leider
nicht schlau genug, da ein sbis draus zu machen.
OK, alles klar!
Da hatte ich einfach einen Denkfehler.
Danke nochmals für die vielen und schnellen Antworten! Wünsche
allerseits ein schönes Wochenende!
mik wrote:
> oder du verwendest micropascal und schreibst den einzeiler:>> bit:=portD.2;
In kommerziellen Embedded-C-Compilern mit entsprechenden
nicht-ANSI-Erweiterungen geht das auch, da brauchts kein Pascal für.
Aber es geht eben nicht in WINAVR-C.
An die doppelte logische Negation hatte ich auch schon gedacht. Auf
welche Weise man es macht, ist aber relativ egal. Der Trick ist nur,
dass man aus dem ursprünglichen Wert einen Wahrheitswert macht, der
entweder 0 oder 1 sein kann. Und den kann man ohne Informationsverlust
einem einzelnen Bit zuweisen.