Frage zu AVR-C

OP #5031952
Hallo,

Was beduetet das "&" ...und was bedeutet das "|" vor dem "="  ??


PORTB |= (1<<1);
                PORTB &= 0x02;

Also prinzipiell ist mir klar dass es ein "oder" bzw. ein "und" ist. 
Aber welche Funktion hat es in diesem Fall?
Angehängte Dateien:
Gast
O. A. schrieb:
> Hallo,
>
> Was beduetet das "&" ...und was bedeutet das "|" vor dem "="  ??
>
> PORTB |= (1<<1);
>                 PORTB &= 0x02;
>
> Also prinzipiell ist mir klar dass es ein "oder" bzw. ein "und" ist.
> Aber welche Funktion hat es in diesem Fall?
1
PORTB &= (1<<1);
ist nur eine andere (verkürzte) Schreibweise für:
1
PORTB = PORTB & (1<<1);

Genauso verhält es sich mit dem "Oder"
O. A. schrieb:
> Aber welche Funktion hat es in diesem Fall?

Es soll Dir veranschaulichen dass Du mal ein gutes C-Buch lesen 
solltest. Denn diese relativ alte Sprache ist offensichtlich alles 
andere als selbsterklärend - ohne ein Buch wie den K&R sieht man keine 
Sonne.

Das Beispiel sind übrigens relativ banale Bitmanipulationen...
Gast
O. A. schrieb:
> Es geht ja darum einen Ausgang anzusteuern.
> Das kann man doch auch so machen.
>
> PORTC = (1<<1);
>
> wozu noch ein &, bzw |....

Nun so ein 8Bit Port hat 8 unterschiedliche Zustände, das sind die 
einzelnen Pin, die man so alle gleichzeitig verändert.
Mit ODER ist in diesem Beispiel nur eins betroffen mit UND ensprechen 
sieben.
Gast
O. A. schrieb:
> Es geht ja darum einen Ausgang anzusteuern.
> Das kann man doch auch so machen.
>
> PORTC = (1<<1);
>
> wozu noch ein &, bzw |....

Weil bei dieser Schreibweise der gesamte Port C auf 0 gesetzt wird außer 
dem einen Bit. Bei der Schreibweise |= wird nur das eine Bit auf 1 
gesetzt und alle anderen unberührt gelassen.
Gast
O. A. schrieb:
> wozu noch ein &, bzw |....

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ver.C3.A4ndern_von_Registerinhalten


schreibst du:
1
PORTB = (1<<1);

wird das gesamte Register PORTB überschrieben.
Bit 7...1 werden gelöscht, unabhängig ihres Zustandes
und nur das erste Bit (Bit 0, LSB) wird gesetzt.
PORTB hat also nach diesem Befehl den Zustand "0000 0001".


verwendest du stattdessen:
1
PORTB |= (1<<1);

wird nur das erste Bit (LSB) im Register PORTB gesetzt (= 1).
Alle anderen Bits bleiben in diesem Fall unverändert.
PORTB hat also nach diesem Befehl den Zustand "xxxx xxxx1".
(x = Zustand vor Ausführung des Befehls)



bzw. analog dazu:
1
PORTB &= ~(1<<1);

hier wird nur das erste Bit (LSB) im Register PORTB gelöscht (= 0).
Alle anderen Bits bleiben in diesem Fall unverändert.
PORTB hat also nach diesem Befehl den Zustand "xxxx xxxx0".
(x = Zustand vor Ausführung des Befehls)
OP
Ok. Danke erstmal.

Das heißt....

1.)------------------------

PORTB |= (1<<1);    (1. Befehl)
PORTB &= 0x02;      (2. Befehl)

Der erste Befehl
Bewirkt zunächst: xxxx xx1x

Der zweite bewirkt
anschließend    : xxxx xx0x

erst an, dann aus...und zwar dasselbe Bit korrekt?

2.)-------------------------

könnte man stattdessen auch schreiben,

PORTB |= (1<<1);
PORTB &= (1<<1);

???? HAt doch die gleiche bedeutung.?


3.)-------------------------

Und abschließend, warum sollte man ein Bit erst an und sofort wieder aus 
machen. Nur ausmachen reicht doch. (Es geht hier um das Einschalten 
einer LEd..)
>> PORTB &= 0x02;      (2. Befehl)
>> was passiert stattdessen?
Bei diesem Befehl werden alle Bits, mit Ausnahme von Bit 1 [7...0] auf 0 
gesetzt.
Bit 1 bleibt dabei unverändert.
Also 000000x0 nach Deiner Schreibweise.

Im Übrigen: Die hier verwendeten Befehle können auch auf beliebige 
Variablen angewendet werden. Es müssen keine Ausgänge sein.
OP
Sebastian S. schrieb:
>>> PORTB &= 0x02;      (2. Befehl)
>>> was passiert stattdessen?
> Bei diesem Befehl werden alle Bits, mit Ausnahme von Bit 1 [7...0] auf 0
> gesetzt.
> Bit 1 bleibt dabei unverändert.
> Also 000000x0 nach Deiner Schreibweise.
>
> Im Übrigen: Die hier verwendeten Befehle können auch auf beliebige
> Variablen angewendet werden. Es müssen keine Ausgänge sein.

das hieße....

PORTB |= (1<<1);    (1. Befehl)
 PORTB &= 0x02;      (2. Befehl)

 Der erste Befehl
 Bewirkt zunächst: xxxx xx1x

 Der zweite bewirkt
 anschließend    : 0000 0010


Hätte man das dann auch direkt mit einem befehl und zwar

PORTB = (1<<1);

realisieren können oder nicht.

Denn ich zitiere:

VIA schrieb:
> schreibst du:
> PORTB = (1<<1);
> wird das gesamte Register PORTB überschrieben.
> Bit 7...1 werden gelöscht, unabhängig ihres Zustandes
> und nur das erste Bit (Bit 0, LSB) wird gesetzt.
> PORTB hat also nach diesem Befehl den Zustand "0000 0010".
O. A. schrieb:
> Hätte man das dann auch direkt mit einem befehl und zwar
>
> PORTB = (1<<1);
>
> realisieren können oder nicht.

Vom logischen Standpunkt her schon. Aber man schaltet Portpins ja nicht 
zum Spaß, sondern weil man damit die externe Hardware, die da dranhängt, 
steuern will. Und dann kann es einen signifikanten Unterschied machen.
Wenn du das Atmelstudio verwendest kannst du dir das Verhalten auch 
direkt anschauen.

Projekt -> 'Name' Properties" unter Tool Simulator auswählen
Debug -> Start Debugging and Break

Rechtsklick auf eine (Globale) Variable und "Add Watch"
oder in der I/O Ansicht den entsprechenden Port auswählen.

Mit "Debug -> Step Into, Step Over" etc. kann man nun die einzelnen 
Schritte nachvollziehen.
O. A. schrieb:
> Ok. Danke erstmal.
>
> Das heißt....
>
> 1.)------------------------
>
> PORTB |= (1<<1);    (1. Befehl)
> PORTB &= 0x02;      (2. Befehl)


2. Ist falsch denn eine AND-Verknüpfung setzt alle Bits auf 0, die nicht 
in beiden Werten 1 sind. Es wird "maskiert" und die Maske hat nur auf 
den 0-zusetzenden Bits eine 0.
1
PORTB &= ~0x02;    //  (2. Befehl)

Die Tilde macht den Unterschied. "bitweises Negieren" im Klartext.

Ob man Bits als Zahl oder geschiftete Eins schreibt? Geschmackssache und 
Aufreger zugleich.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.