Forum: Mikrocontroller und Digitale Elektronik Frage zu ODER-Verknüpfung


von Tim (Gast)


Lesenswert?

ich habe mal eine Frage zu diesem Beispiel. Ich habe es mir auch mehrere 
male durchgelesen, aber irgendwie will es nicht in meinem Kopf rein. 
LINK
http://www.mikrocontroller.net/articles/Bitmanipulation
1
DDRA |= (1 << DDA0) | (1 << DDA2);
kurze Fassung
1
 DDRA = DDRA | (1 << DDA0) | (1 << DDA2);
 lange Fassung

Bei DDA0 und DDA2 sind die Pins auf 1 gestellt, das ist klar. Was ist in 
dem Fall "= DDRA"? ist das eine 1 oder eine 0 oder gar nichts vom 
beiden? Mir platzt gleich der Schädel.


gruß
Tim

von Peter II (Gast)


Lesenswert?

Tim schrieb:
> Bei DDA0 und DDA2 sind die Pins auf 1 gestellt, das ist klar.
nein das ist nicht klar.

DDA* sind nur zahlen von 0-7 und geben das bit an. Sie stellen aber kein 
Bit dar!

von Thomas (Gast)


Lesenswert?

Hey,

grundsätzlich werden in deiner Zuweisung ja keine einzelnen Bits 
verknüpft, sondern alle Bits innerhalb eines Bytes.

DDRA |= (1 << DDA0) | (1 << DDA2);
DDRA = DDRA | (1 << DDA0) | (1 << DDA2);

Diese Zeilen sind zunächst völlig gleichwertig - dazu musst du nicht 
einmal verstehen, was genau passiert. Das liegt an dem 
Zuweisungsoperator "=" und "|=". Die sind eben so definiert (siehe 
C-Tutorial).

DDRA = DDRA | (1 << DDA0) | (1 << DDA2);

Hier werden dann im Grunde 3 Bytes mit einander "verodert", welche du 
dir alle als 8Bit vorstellen kannst.

Zunächst DDRA, wobei man hier nicht genau wissen kann, wie DDRA 
aussieht. Dann kommen die nächsten Bytes:

(1 << DDA0) entspricht 0000.0001
(1 << DDA2) entspricht 0000.0100

Vielleicht solltest du dir Byte-Operationen nochmal genauer im Tutorial 
ansehen.

Grüße,
  Thomas

von Tim (Gast)


Lesenswert?

>DDA* sind nur zahlen von 0-7 und geben das bit an. Sie stellen aber kein
>Bit dar!

ach so, du meinst die position.

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> ich habe mal eine Frage zu diesem Beispiel. Ich habe es mir auch mehrere
> male durchgelesen, aber irgendwie will es nicht in meinem Kopf rein.
> LINK
> http://www.mikrocontroller.net/articles/Bitmanipulation
>
>
1
DDRA |= (1 << DDA0) | (1 << DDA2);
kurze Fassung
>
1
 DDRA = DDRA | (1 << DDA0) | (1 << DDA2);
 lange Fassung

Fast
1
  DDRA = DDRA | ( (1 << DDA0) | (1 << DDA2) );

>
> Bei DDA0 und DDA2 sind die Pins auf 1 gestellt, das ist klar. Was ist in
> dem Fall "= DDRA"?

Der INhalt des DDRA Registers. So wie er sich beim Auslesen präsentiert.

von Pako (Gast)


Lesenswert?

DDA0 und DDA2 sind Bitpositionen.
1
DDRA |= (1 << DDA0) | (1 << DDA2);
wird zu
1
DDRA |= (1 << 0) | (1 << 2);
wird zu
1
DDRA |= 0x01 | 0x04;
wird zu
1
DDRA |= 0x05;

von Michael H. (michael_h45)


Lesenswert?

Tim schrieb:
> Bei DDA0 und DDA2 sind die Pins auf 1 gestellt, das ist klar. Was ist in
naja...
Was wirklich gemacht wird: Die Bits, die zu DDA0 und DDA1 gehören, 
werden 1 gesetzt und der Rest vom Wort bleibt unverändert.

> dem Fall "= DDRA"? ist das eine 1 oder eine 0 oder gar nichts vom
> beiden? Mir platzt gleich der Schädel.
Links vom = ist eine Schreiboperation, rechts davon eine Leseopertaion.

DDRA    =   DDRA | (1 << DDA0) | (1 << DDA2);

neuer   =   aktu-  | 0b00000001  |  0b00000100
Wert        eller
von         Wert
DDRA        DDRA

Beispiel: DDRA ist aktuell 0b11000100.

aktuell:   0b11000100
         | 0b00000001
         | 0b00000100
         ------------
           0b11000101   neuer Wert

von Tim (Gast)


Lesenswert?

>> dem Fall "= DDRA"? ist das eine 1 oder eine 0 oder gar nichts vom
>> beiden? Mir platzt gleich der Schädel.
> Links vom = ist eine Schreiboperation, rechts davon eine Leseopertaion.
>
> DDRA    =   DDRA | (1 << DDA0) | (1 << DDA2);
>
> neuer   =   aktu-  | 0b00000001  |  0b00000100
> Wert        eller
> von         Wert
> DDRA        DDRA
>
> Beispiel: DDRA ist aktuell 0b11000100.
>
> aktuell:   0b11000100
>          | 0b00000001
>          | 0b00000100
>          ------------
>            0b11000101   neuer Wert

danke Leute für die schnellen antworten.

woher weiß ich denn, was der aktuelle Wert in meinem Beispiel ist?
1
  PORTA |= (1<<PA0);
2
  PORTA &= ~(1<<PA2);
3
  
4
  DDRA |= (1 << DDA0) | (1 << DDA2);
5
  while (1)
6
  {
7
    _delay_ms (250);
8
    PORTA ^= (1 << PA0) | (1 << PA2);
9
  }


gruß
Tim

von Peter II (Gast)


Lesenswert?

Tim schrieb:
> oher weiß ich denn, was der aktuelle Wert in meinem Beispiel ist?

ist doch egal - du musst es nicht wissen. du willst ja nur ein oder 
mehrere Bits setzen. Egal was vorher drin war.

von Tim (Gast)


Lesenswert?

Dann kann man doch "...=  DDRA..." eigentlich weglassen oder? verwirrt 
doch nur.

von Pako (Gast)


Lesenswert?

Tim schrieb:
> Dann kann man doch "...=  DDRA..." eigentlich weglassen oder? verwirrt
> doch nur.

Nein.
Du willst bestimmte Bits setzen und die anderen Bits so lassen wie sie 
sind.

Wenn Du
1
DDRA = 0x10;
schreibst, ist das was anderes als
1
DDRA |= 0x10;

Im ersten Fall ist der Inhalt von DDRA danach ganz genau 0x10.
Im zweiten Fall ist der Inhalt von DDRA danach so, wie er vorher war, 
außer daß Bit 4 (0x10) jetzt gesetzt ist.

von Michael H. (michael_h45)


Lesenswert?

Tim schrieb:
> Dann kann man doch "...=  DDRA..." eigentlich weglassen oder? verwirrt
> doch nur.

Überleg dir anhand von meinem Beispiel, was der Unterschied am Ergebnis 
(neuer Wert) ist, wenn du den aktuellen Wert weglässt oder nicht.

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:
> Dann kann man doch "...=  DDRA..." eigentlich weglassen oder? verwirrt
> doch nur.

Der Witz an der Sache ist doch genau der, dass es dich nicht kümmert, 
wie die anderen DDRA Bits stehen. Du willst genau die beiden angegebenen 
auf 1 haben, welchen Zustand die anderen haben interessiert dich doch 
überhaupt nicht.

Es ist dies die Form für minimalinvasiven Eingriff. Das was du erreichen 
willst, erreichst du (nämlich die beiden Bits auf 1 zu setzen). Und der 
Rest bleibt so wie er ist - was immer das auch sein mag.

Denn genau anders rum wird ein Schuh draus.

   DDRA = ( 1 << PD0 ) | ( 1 << PD1 );

Genau jetzt erhebt sich nämlich die Frage: Neben den beiden Bits, was 
genau verändere ich eigentlich noch, indem ich die restlichen Bits auf 0 
zwinge? Genau jetzt musst du Dinge beachten, die du im anderen Fall 
ignorieren kannst. Jetzt hast du plötzlich Nebenwirkungen, deren 
Auswirkungen du überblicken musst.

von Pako (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Der Witz an der Sache ist doch genau der, dass es dich nicht kümmert,
> wie die anderen DDRA Bits stehen.

Mit Verlaub:
Ich fürchte, daß diese Formulierung von einem Anfänger mißverstnanden 
werden könnte als:
"Es ist doch egal, was mit den anderen Bits passiert, also kann ich 
diese auch mit einem beliebigen Wert überbügeln."
Er sollte unbedingt verstehen, daß die anderen Bits so bleiben SOLLEN, 
wie sie vorher waren und nicht verändert werden.

von Tim (Gast)


Lesenswert?

1
DDRA = DDRA | (1 << DDA0) | (1 << DDA2);
1
DDRA = DDRA | ( (1 << DDA0) | (1 << DDA2) );

Im Prinzip ist es doch das gleiche? wie schlimm ist es denn wenn man die 
Klammern weglässt?

gruß Tim

von doppelt invertierte Salatgurke (Gast)


Lesenswert?

Tim schrieb:
> Im Prinzip ist es doch das gleiche?
ja
> wie schlimm ist es denn wenn man die
> Klammern weglässt?
gar nicht schlimm, passiert nichts.

von Stefan E. (sternst)


Lesenswert?

Tim schrieb:
> DDRA = DDRA | (1 << DDA0) | (1 << DDA2);
> DDRA = DDRA | ( (1 << DDA0) | (1 << DDA2) );
>
> Im Prinzip ist es doch das gleiche? wie schlimm ist es denn wenn man die
> Klammern weglässt?

In diesem Fall ist es egal.

Aber z.B. bei
1
a *= b + c;
ist es ein großer Unterschied, ob das nun äquivalent zu (falsch)
1
a = a * b + c;
 oder (richtig)
1
a = a * (b + c);
ist.

von Tim (Gast)


Lesenswert?

ok. verstehe. Danke

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.