Frage zu Bitoperatoren in C (AVR)

OP #5427559
Lesenswert?

Hallo,

was bedeutet das (1<<PB2) ?

PB steht wohl für PortB.. Muss man das dem MC noch mitteilen oder weiß 
der das.



if (PINB & (1<<2)||(PINB & (1<<3)))

wenn ich soetwas habe, soll das bedeuten wenn "PinB2 = 1" oder "PinB3 = 
1"
dann wäre die Bedingung erfüllt?

Und wäre dann (0<<PB2) = PortB2 = 0?

Danke.
#5427581
Lesenswert?

O. A. schrieb:

> was bedeutet das (1<<PB2) ?

PB2 ist irgendwo in einem AVR-spezifischen Headerfile als 2 definiert.
Damit bedeutet das '1 um 2 Bits nach links geschoben' und soll als 
Bitmaske für PortB Bit 2 stehen. Kann man auch als 0x04 schreiben oder 
00000100 binär (wobei das kein Standard-C ist).


> PB steht wohl für PortB.. Muss man das dem MC noch mitteilen oder weiß
> der das.

Das muss man dem C-Compiler mitteilen, i.d.R. durch inkludieren einer 
passenden Headerdatei. Das hat alles schon einmal jemand definiert.



> if (PINB & (1<<2)||(PINB & (1<<3)))
>
> wenn ich soetwas habe, soll das bedeuten wenn "PinB2 = 1" oder "PinB3 =
> 1"
> dann wäre die Bedingung erfüllt?

Ja.



> Und wäre dann (0<<PB2) = PortB2 = 0?

Nein.

if (PINB & (1<<2)) ist die Kurzform für
if ((PINB & (1<<2)) != 0)


Das Inverse wäre dann
if ((PINB & (1<<2)) == 0)
oder
if (!(PINB & (1<<2)))
Gast #5427630
Lesenswert?

Wolfgang schrieb:
> Nein, das "PB" ist dabei völlig bedeutungslos. Entscheiden ist die 2 und
> die steht für das zweite Bit (irgendeines Bytes, das kann genauso Port C
> sein).
Das ist nicht ganz richtig!
Ein bisschen Sorgfalt kann auch dort nicht schaden!

Beispiel:
Beim ATMega328P ist PC7 nicht definiert.
PB7 dagegen existiert.

Es ist also nicht immer bedeutungslos, ob B oder C.
Gast #5427755
Lesenswert?

Arduino F. schrieb:
> Das ist nicht ganz richtig!

Was ist  daran nicht richtig?

Welche Bedeutung hat denn das "PB" deiner Meinung, außer dass es ein 
Namensteil ist, der genauso gut auch MEINPORTBIT heißen könnte

> Beim ATMega328P ist PC7 nicht definiert.
> PB7 dagegen existiert.

Da kommt man hinter, spätestens wenn der Compiler meckert. Nicht 
definierte Zeichenketten zu verwenden, bringt natürlich nichts.

Trotztdem verbirgt sich sowohl hinter PB6 als auch hinter PC6 die Zahl 
6, vorausgesetzt es gibt beide in der betreffenden Prozessordefinition.
Gast #5427768
Lesenswert?

Wolfgang schrieb:
> Welche Bedeutung hat denn das "PB" deiner Meinung,
>....
> Da kommt man hinter, spätestens wenn der Compiler meckert.

Genau!
Das hast du gut erkannt.
Und darum sollte man auch die richtigen Bezeichner verwenden, damit der 
Compiler eine Chance hat.

Hier mal ein schlechtes Beispiel:
PORTC |= (1<<PB7)
Der Kompiler ist still!

So musses:
PORTC |= (1<<PC7)
Der Kompiler schreit

Wolfgang schrieb:
> außer dass es ein
> Namensteil ist, der genauso gut auch MEINPORTBIT heißen könnte
Zuhause kannst du alles so nennen, wie du willst.
Aber die Verwendung von PB7 oder auch PB2 sind feste Konventionen.
#5427866
Lesenswert?

Christian H. schrieb:
> Arduino F. schrieb:
>> Es ist also nicht immer bedeutungslos, ob B oder C.
>
> Da PB2 = PC2 = 2, ist es im Prinzip egal, was man verwendet.

Es ist nur in diesem speziellen Fall egal. Weil bei Atmel netterweise 
die Numerierung von Pins und Bits in den Steuerregistern gleich ist.

Wolfgang schrieb:
> Welche Bedeutung hat denn das "PB" deiner Meinung, außer dass es ein
> Namensteil ist, der genauso gut auch MEINPORTBIT heißen könnte

Genau das ist der wichtige Teil. Genau deswegen verwendet man sprechende 
Bezeichner für Makros (wie hier) oder Variablen (anderswo). PB2 ist die 
Nummer des Steuerbits für den Pin mit dem Namen PB2. Und weil man 
entsprechende Makros für die Steuerbits aller Pins hat, muß und will 
man sich gar nicht mehr damit auseinandersetzen, ob PB2 und PC2 am Ende 
zur gleichen Nummer werden.

Wenn man den Pin PB2 in DDRB/PINB/PORTB anspricht, verwendet man einfach 
das PB2 Makro und fertig. Das ist einfach (lesbar) und selbsterklärend. 
Zugegeben, bei der sehr regulären Anordung der IO-Pins scheint das etwas 
überzogen, aber bei anderen Steuerbits (z.B. beim UART) wird es sofort 
klar, warum man die (und genau nur die) Makros aus den Headerfiles 
nehmen will.
#5428102
Lesenswert?

Axel S. schrieb:
> Und weil man
> entsprechende Makros für die Steuerbits aller Pins hat, muß und will
> man sich gar nicht mehr damit auseinandersetzen, ob PB2 und PC2 am Ende
> zur gleichen Nummer werden.

Andererseits glaube ich kaum, dass jemand ein
1
PORTD = 0x11;
gegen
1
PORTD = (1<<PORTD5) | (1<<PORTD1)
austauschen würde. Oder hat wer für sowas einen entsprechenden "switch" 
Verteiler? :D
#5428161
Lesenswert?

Axel S. schrieb:
> Wolfgang schrieb:
>> Welche Bedeutung hat denn das "PB" deiner Meinung, außer dass es ein
>> Namensteil ist, der genauso gut auch MEINPORTBIT heißen könnte
>
> Genau das ist der wichtige Teil. Genau deswegen verwendet man sprechende
> Bezeichner für Makros (wie hier) oder Variablen (anderswo). PB2 ist die
> Nummer des Steuerbits für den Pin mit dem Namen PB2. Und weil man
> entsprechende Makros für die Steuerbits aller Pins hat, muß und /will/
> man sich gar nicht mehr damit auseinandersetzen, ob PB2 und PC2 am Ende
> zur gleichen Nummer werden.

Das Problem ist jedoch, dass man auch
1
TCCR0A |= (1 << WGM02);
schreiben kann, und der Compiler es übersetzt. Denn TCCR0A ist vom Typ 
volatile uint8_t und (1 << WGM02) hat den Typ int, und das ist implizit 
konvertierbar.

Besser wäre es, wenn TCCR0A einen speziellen Typ hätte und es für die 
Bits des TCCR0A und TCCR0B jeweils auch andere Typen geben würde, die 
dann inkompatibel sind, so dass der obige Code zu einem Compilzeitfehler 
führt.

Das lässt sich mit C aber leider nicht machen (mit anderen Sprachen 
schon).
OP #5428569
Lesenswert?

ich habe noch eine Frage.

was bedeutet "==", entspricht das in Assembler etwa "cpi" ?

Das heißt wenn zwei Ausdrücke gleich sind, wird das Z-Flag gesetzt?

Und was ist bedeutet "&=~"

Portb &=~ (1<<PB7)

wobei "~" eine bitweise negation ist. aber in Zusammenhang mit dem dem 
Gleich und "&"?

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