Forum: Mikrocontroller und Digitale Elektronik C syntaxproblem


von Benni (Gast)


Lesenswert?

kurze knackige frage:

"  // Alle Pins des Ports B als Ausgang definieren:
  DDRB = 0xff;
  // Pin0 wieder auf Eingang und andere im ursprünglichen Zustand 
belassen:
  DDRB &= ~( 1 << DDB0 );
  // Pin 3 und 4 auf Eingang und andere im ursprünglichen Zustand 
belassen:
  DDRB &= ~( ( 1 << DDB3 ) | ( 1<<DDB4) );
  // Pin 0 und 3 wieder auf Ausgang und andere im ursprünglichen Zustand 
belassen:
  DDRB |= ( 1 << DDB0) | ( 1 << DDB3 );
  // Alle Pins auf Eingang:
  DDRB = 0x00; "

warum wird bei der invertierung &= und bei normalgebrauch |= benutzt?
der rest versteh ich

von ggast (Gast)


Lesenswert?

Schau dir mal die Bedeutung des bitweisen UND und ODER an.

Wenn du etwas mit 1 veroderst bekommst du definitiv eine 1 wenn du eine 
0 veroderst bleibt der Ursprungszustand des Vergleichsbits erhalten.

Wenn du etwas mit 0 verundest bekommst du definitiv eine 0, wenn du 
etwas mit 1 verundest bleibt der Ursprungszustand erhalten.

Das wird gemacht, wenn "nur bestimmte" Bits verändert werden sollen und 
der Rest innerhalb des Bytes unverändert bleiben soll.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Benni schrieb:
> warum wird bei der invertierung &= und bei normalgebrauch |= benutzt?

Was macht die logische Operation UND, und was macht die logische 
Operation ODER?

>   DDRB &= ~( 1 << DDB0 );

Schreib Dir mal in Form von 8-Bit-Binärzahlen auf, was

- in DDRB steht, bevor die Zeile ausgeführt wird
- was "DDB0" ist
- was 1 << DDB0 ist
- was ~(1 << DDB0) ist

und was DDRB & dieser letzte Wert ist.

Dasselbe wiederholst Du für

>  DDRB |= ( 1 << DDB0) | ( 1 << DDB3 );

- was steht vorher in DDRB?
- was sind DDB0 und DDB1?
- was ist 1 << DDB0?
- was ist 1 << DDB3?
- was ist (1 << DDB0) | (1 << DDB3)?

Und was ergibt DDRB | dieser letzte Wert?

von Benni (Gast)


Lesenswert?

aaaaahhhhh alles klar... durch die invertierung würde das mittels | das 
vorher gespeicherte an den anderen stellen ändern was wir ja ned 
wollen... danke!

von Benni (Gast)


Lesenswert?

aber warum schreibt man statt

 DDRB &= ~( 1 << DDB0 )

nich einfach

 DDRB |= (0 << DDB0 )


?

von Benni (Gast)


Lesenswert?

ach geht ja garnich... hat sich erledigt ^^

von fdast (Gast)


Lesenswert?

DDB0 und DDB3 sind Postionen der Datenrichtungsregister und in der 
einzubindenden Systembibliothek avr/io.h ist für diese Bezeichnungen 
DDB3=PINB3=3 und DDB0=PIN0=0 definiert.
DDRB ist die Datenrichtungsregister an Port B, 0 ist für Eingang, 1 ist 
für Ausgang. Das ist ein 8 Bitmuster.

Pin 0 und 3 an Port B als Ausgang definieren:
DDRB |= ((1<<DDB0) | (1<<DDB3))
Pin 0 an Port B als Eingang definieren:
DDRB &= ~( 1 << DDB0 )
Pin 3 an Port B als Ausgang definieren:
DDRB |= 1<<DDB3

von Kaj (Gast)


Lesenswert?

Benni schrieb:
> aber warum schreibt man statt
>
>  DDRB &= ~( 1 << DDB0 )
>
> nich einfach
>
>  DDRB |= (0 << DDB0 )

Benni schrieb:
> ach geht ja garnich... hat sich erledigt ^^

Das scheitert schon daran, das man (soweit ich weiss) eine 0 nicht 
shiften kann. ;)

von Maxx (Gast)


Lesenswert?

Kaj schrieb:
> Das scheitert schon daran, das man (soweit ich weiss) eine 0 nicht
> shiften kann. ;)

Dann denk nochmal nach. Ergibt das Sinn?
Fragst du eine Variable auf 0 ab, bevor du Bits verschiebst?

In dem zitierten Fall wird es noch nicht mal vom Programm berechnet 
sondern schon vom Kompiler ausgewertet, da konstant.

0b00000000 um x nach y verschoben ist ...?

von Falk B. (falk)


Lesenswert?


von fdast (Gast)


Lesenswert?

Man kann auch 0 schiften aber nach der Verschiebung hat man wiederum 0 
und ein Bitmaske von 0 hat keine Informationen und das ist sinnlos für 
eine Bitoperation.

DDRB &= ~( 1 << DDB0 ) Bit 0 an Port B ist Eingang (Korrekt)

DDRB |= (0 << DDB0 ) ist Blödsinn! (Bit 0 an Port B kann Eingang oder 
Ausgang sein!)

Man muss auch Datenrichtungsregister nicht per Hand definieren z.B.
wenn man schreibt DDRB=0000 1000 (Pin 3 an Port B als Ausgang definiert)
Dadurch gehen die Information von den anderen Pins an Port B verloren 
also Korrekt  ist:
DDRB |= 1<<DDB3 (Pin 3 an Port B als Ausgang definieren)
Pin 3 an Port B als Eingang definieren:
DDRB &= ~( 1 << DDB3 )

von Tom (Gast)


Lesenswert?

fdast schrieb:
> Man kann auch 0 schiften aber nach der Verschiebung hat man
> wiederum 0
> und ein Bitmaske von 0 hat keine Informationen und das ist sinnlos für
> eine Bitoperation.
Aber manchmal sinnvoll für die Lesbarkeit, um Bits, die 0 bleiben 
sollen, explizit zu benennen:
1
BREAKFAST_CONF = (1 << COFFEE) | (0 << TEA) |
2
    (1 << WHISKEY) | (0 << BEER) |
3
    (1 << CEREAL) | (1 << MILK) |
4
    (0 << BREAD) | (0 << JAM);

von Paul Baumann (Gast)


Lesenswert?

@Tom

Du hast aber appetitliche Bits in Deinen Registern... Trotzdem schmeckt
mir "C" imer noch nicht.
;-)

MfG Paul

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.