Frage zu ODER-Verknüpfung

Gast #2757244
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
Gast #2757251
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
#2757255
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.
#2757265
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
Gast #2757283
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
Gast #2757301
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.
#2757352
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.
Gast #2757362
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.
#2759382
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren