PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänger Fragen umstieg auf C.



humus
27.12.2006, 20:35
Hey,

ich noch ziemlich Neu im Bereich C und AVR.

Da hätte ich mal eine Frage zum Thema Zuweisung von einzelnen Bits.

erste möglichkeit:
PORTB |= (1<<PORTB2);

zweite möglichkeit:
PORTB = (1<<PORTB2);

Was ist da der Unterschied?

Wieso wird die erste möglichkeit "normalerweiße" genommen?
für mich ist das von der Funktion kein Unterschied.

Das erst heißt ja erst oder dann zuweisen, aber wieso verwende ich das da bei dieser zuweisung?

Das zweite ist ja einfach nur zuweisen!

Vielleicht kann mir dass ja mal einer erläutern! =)

Dann noch eine Frage, gibt es einen einfachen befehl um einen Ausgang umzukehren(Invertieren) ?

In Bascom gibt es den Befehl "Toggle" gibt es etwas vergleichbares auch in C? Oder muss ich mir da selber eine Funktion erstellen, die das für mich übernimmt?

SprinterSB
27.12.2006, 20:45
1) heisst ja
POTRB = PORTB | (1 << PORTB2);

Da | nur Bits setzen kann, wird das PORTB2-te Bit gesetzt (die anderen Bits bleiben erhalten, da sie eingelesen und unverändert wieder geschrieben werden), während in PORTB = (1 << PORTB2) noch alle anderen Bits auf 0 gesetzt werden.

Um einen Port zu invertieren kannst du den Wert merken oder schreiben
PORTRB ^= (1 << PORTB2);
^ ist XOR

humus
27.12.2006, 20:59
Dankeschön, für deine schnelle Hilfe! =)

Werde mich die nächsten Tage bestimmt öfter hier melden! ;-)

humus
30.12.2006, 20:48
Hey,

so mal wieder eine kleine Frage! ;-)

Warum funktioniert folgendes nicht?

PORTB |= (0 << PORTB0);

Da weiße ich doch quasi einfach nur die Null zu, oder?

PORTB |= (1 << PORTB0);

Da weiße ich ein High bit zu also die 1.
Das funktioniert, aber wieso funktioniert das mit dem LOW-Bit nicht?

Pascal
31.12.2006, 11:15
Das kann nicht funktionieren, da bei einer Oder-Verknüpfung die 1 dominant ist.
Also, wenn bei


PORTB |= (0 << PORTB0);

das Bit PORTB0 eine 1 ist, ist es nach dem Befehl immer noch eine 1. Denn 0 | 1 = 1.

Du musst stattdessen folgendes verwenden:


PORTB &= ~(1 << PORTB0);

humus
31.12.2006, 11:32
Dankeschön, da hätte ich auch mal selbst drauf kommen können! ](*,) ](*,) ](*,)

uwegw
31.12.2006, 12:41
Warum funktioniert folgendes nicht?

PORTB |= (0 << PORTB0);

Da weiße ich doch quasi einfach nur die Null zu, oder?

NEIN! Damit weist du keine Null zu! Eine sehr beliebte Falle im C: das << heißt nicht, dass das Bit PORTB0 auf eine bestimmten wert gesetzt wird.
Es ist der Verscheibe- oder Shift-Operator. Er nimmt das Byte, in dem die 1 steht, und verscheibt darin die Bits nach links, und zwar um so viele Stellen, wie es durch den Wert rechts von << bestimmt wird. Und PORTB0 ist als 0 definiert. Somit ergibt sich dann in der Klammer ein Wert von 00000001, der dann mit dem alten Portwert verODERt wird. Somit wird das Bit an der Stelle 0 gesetzt.

Damits deutlicher wird das ganze mal mit PORTB5, was intern als 5 definiert ist.
(1<<PORTB5)
wird übersetzt zu
(1<<5)
Das heißt, wir nehmen das Byte mit der eins darin
00000001
und schieben es fünfmal nach links:
00100000
Damit haben wir nen ein Byte erzeugt, in dem das fünfte Bit gesetzt ist. Und wenn wir das jetzt mit dem Port-Register verodern, in dem z.B. gerade nen 10000110 steh, ergibt sich:
10100110
Wir haben also das fünfte Bit des Ports gesetzt und den Rest in Ruhe gelassen.


Wenn man ein Bit im Port wieder löschen will, macht man es ja mit
PORTB &= ~(1 << PORTB5);

Dabei wird erst wieder über die Verscheibung das Byte mit der
00100000
erzeugt. Dann wird es mit dem ~ Bitweise invertiert:
11011111
und schließlich per & (AND) mit dem Portregister verknüpft:
10100110 alter Wert im Port
11011111 Byte mit ausgewähltem Bit, das wir löschen wollen
------------
10000110 Ergebnis