Forum: Mikrocontroller und Digitale Elektronik Frage zur Bitmanipulation


von Frank92 (Gast)


Lesenswert?

Hallo,

wir haben von unseren Lehrer ein Programmcode bekommen.

Folgende Zeile ist mir unverständlich:


// Set Pin5 to low
PORTD &= ~(0<<PD5);


Der Ausdruck in den runden Klammern ist doch immer 0b00000000 und 
invertiert 11111111, somit bleibt PORTD immer gleich.

Die ganze Zeile ist also überflüssiges Stück Code?

Könnte es sein, dass hier eigentlich (1<<PD5) gemeint wurde ?

Grüße

Frank

von Martin K. (maart)


Lesenswert?

Ja.

von bitmask (Gast)


Lesenswert?

Ja, 1<<Portpin ist gemeint.

Das ist die blöde Schreibweise, die ein Praktikant bei Atmel nach der 
Weihnachtsfeier erfunden hat. Alle anderen machen es richtig und nutzen 
definierte Masken in den Headern.

So und jetzt können die AVR Jünger auf mich einschlagen. ;-)

von Wolfgang (Gast)


Lesenswert?

Frank92 schrieb:
> Könnte es sein, dass hier eigentlich (1<<PD5) gemeint wurde ?

Muss nicht. Es kommt auf das Lernziel an.

Es gibt Leute, die schreiben alle Bitwerte einer Maske in dieser 
Schreibweise hin, d.h. sowohl 0, als auch 1. Ändern tut die "0" nichts, 
erhöhen aber für manchen die Lesbarkeit im Kontext.

von Frank92 (Gast)


Lesenswert?

Vielen Dank für eure Antworten !

von bitmask (Gast)


Lesenswert?

Wolfgang schrieb:
> erhöhen aber für manchen die Lesbarkeit im Kontext.

Was wir hier gut erkennen können. :'(

von Wolfgang (Gast)


Lesenswert?

bitmask schrieb:
> Was wir hier gut erkennen können. :'(

Das bringt natürlich nichts, wenn die Kommentare nicht zum Code passen 
;-)

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> Wolfgang schrieb:
>> erhöhen aber für manchen die Lesbarkeit im Kontext.
>
> Was wir hier gut erkennen können. :'(

Mit einer Zeile ist die (0<<PD2) natürlich Quatsch. Wenn man aber
die Initialisierung eines ganzen Ports bzw. oder auch mehr
auf diese Weise schreibt, sieht man gleich, wo etwas geändert
werden soll und wo nicht.

Ein Beispiel:
1
TCCR0B =     ((0<<FOC0A)    //
2
            | (0<<FOC0B)    //force output compare -> 0
3
            | (0<<WGM02)    //waveform generation mode: normal
4
            | (1<<CS02)     // 
5
            | (0<<CS01)     //
6
            | (1<<CS00));   //clock select: clk/1024 -> 14,4kHz = 69,4µs
7
8
9
ENC1_PORT =  ((0<<PD7)          //Pull Up's einschalten
10
            | (1<<PD6) 
11
            | (0<<PD5) 
12
            | (0<<PD4) 
13
            | (1<<PD3) 
14
            | (0<<PD2));

von bitmask (Gast)


Lesenswert?

Karl der Käfer schrieb:
> Ein Beispiel:
> TCCR0B =     ((0<<FOC0A)    //
>             | (0<<FOC0B)    //force output compare -> 0
>             | (0<<WGM02)    //waveform generation mode: normal

Sorry, aber wesentlich besser ist
1
TCCR0B =     (FOC0A    //
2
            | FOC0B    //force output compare -> 0
3
            | WGM02    //waveform generation mode: normal
4
             ...
wenn es einen vernüftigen Header gibt.

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> Karl der Käfer schrieb:
>> Ein Beispiel:
>> TCCR0B =     ((0<<FOC0A)    //
>>             | (0<<FOC0B)    //force output compare -> 0
>>             | (0<<WGM02)    //waveform generation mode: normal
>
> Sorry, aber wesentlich besser istTCCR0B =     (FOC0A    //
>             | FOC0B    //force output compare -> 0
>             | WGM02    //waveform generation mode: normal
>              ...
> wenn es einen vernüftigen Header gibt.

Das ist gerade das, was nicht beabsichtigt ist. Ich will hier das
Bit FOC0B nicht setzen, du setzt es.
...und wie sieht dann der "vernüftige" Header ab der nächsten Zeile aus?
Warum hörst du auf mit zitieren, wenn's interessant wird?
Es kommt ja gerade darauf an, zu sehen, ob ein Bit gesetzt werden
soll oder nicht verändert werden soll...
In diesem Fall soll CS02 und CS00 gesetzt werden und die restlichen
Bits von TCCR0B (die alle aufgezählt sind) nicht:
Karl der Käfer schrieb:
> TCCR0B =     ((0<<FOC0A)    //
>             | (0<<FOC0B)    //force output compare -> 0
>             | (0<<WGM02)    //waveform generation mode: normal
>             | (1<<CS02)     //
>             | (0<<CS01)     //
>             | (1<<CS00));   //clock select: clk/1024 -> 14,4kHz = 69,4µs


Wie unterscheidest du in deiner Schreibweise, ob das Bit nun gesetzt 
werden
soll oder nicht?

von bitmask (Gast)


Lesenswert?

Du Pappnase :-P

Hier wird das Ganze Register mit = bearbeitet. Ich brauche nur die 1er 
setzen. :-*  Und wenn ich die nicht benötigten Bits unbedingt als 
Kommentar möchte, dann kommentiere ich sie aus. :-D
Ein Kommentar ist ein Kommentar und kein Code, wie bei dir. ;-)

PS
Wie ein Zeilenkommenter aussieht, ist dir geläufig? :-P

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> Du Pappnase :-P
>
> Hier wird das Ganze Register mit = bearbeitet. Ich brauche nur die 1er
> setzen. :-*  Und wenn ich die nicht benötigten Bits unbedingt als
> Kommentar möchte, dann kommentiere ich sie aus. :-D
> Ein Kommentar ist ein Kommentar und kein Code, wie bei dir. ;-)
>
> PS
> Wie ein Zeilenkommenter aussieht, ist dir geläufig? :-P

Aha, jeder, der eine andere Philosophie hat, ist bei dir also eine 
"Pappnase". Wenn dem so ist, können wir die Diskussion beenden. Du 
machst es so, wie du es willst und ich bin auf meine Art gut gefahren. 
Und keines von beiden ist falsch.

Die eigentliche Frage hast du nicht beantwortet, warum du denn die Bits, 
die NICHT gesetzt werden sollen, aufzählst und diejenigen, die gesetzt 
werden sollen nicht. Und das begründest du mit einem "vernünftigen 
Header".

bitmask schrieb:
> Sorry, aber wesentlich besser istTCCR0B =     (FOC0A    //
>             | FOC0B    //force output compare -> 0
>             | WGM02    //waveform generation mode: normal
>              ...

bitmask schrieb:
> Wie ein Zeilenkommenter aussieht, ist dir geläufig? :-P

Wie du siehst, ist mir das geläufig (Beispiel von oben) :-)
Karl der Käfer schrieb:
> ENC1_PORT =  ((0<<PD7)          //Pull Up's einschalten

von Karl der Käfer (Gast)


Lesenswert?

Im übrigen sparen auskommentierte Zeilen in diesem Falle KEINEN Code, 
weil die Zeilen

Karl der Käfer schrieb:
> TCCR0B =     ((0<<FOC0A)    //
>             | (0<<FOC0B)    //force output compare -> 0
>             | (0<<WGM02)    //waveform generation mode: normal
>             | (1<<CS02)     //
>             | (0<<CS01)     //
>             | (1<<CS00));   //clock select: clk/1024 -> 14,4kHz = 69,4µs

insgesamt nur eine Zuweisung zu TCCR0B erzeugen.

von Toxic (Gast)


Lesenswert?

Fuer "PIC-Freaks" Definitionen um ein Bit zu setzen/loeschen/testen

#define bitset(var,bitno) ((var) |= (1 << (bitno)))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
#define bittst(var,bitno) (var & (1 << (bitno)))

von bitmask (Gast)


Lesenswert?

Karl der Käfer schrieb:
> Die eigentliche Frage hast du nicht beantwortet, warum du denn die Bits,
> die NICHT gesetzt werden sollen, aufzählst und diejenigen, die gesetzt
> werden sollen nicht.

Ich sach doch, Pappnase. ;-)

Dein Horizont beschränkt sich auf avr mit kleinen Registern. Aber auch 
schon vor der ARM-Welle gab es andere MCs mit mehr Inhalt. ;-)
Und damit man sich nicht durch zig Zeilen wertlosen Code (deine 
Kommentare) hangeln muss, schreibt man es richtig hin.

Denk einmal an zusammengefasste BITs für die Bedeutung (wie man sie aus 
vernünftigen Headern kennt):
1
#define MODE_SLOW  TMOD0
2
#define MODE_Medium (TMOD1 | TMOD0)
3
...
4
ModRegister = ... | MODE_MEDIUM | ...;

Bei deinem Beispiel
(0<<PD7)
sind 5 von 8 Zeichen überflüssig. Das sind über 60% Abfall (ein 
Kommentar steht ja noch dahinter)!

Denn mal weiter so. ;(((

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> sind 5 von 8 Zeichen überflüssig. Das sind über 60% Abfall

Im Code? ;-)
(denn das hast du behauptet)

bitmask schrieb:
> Ein Kommentar ist ein Kommentar und kein Code, wie bei dir. ;-)

von bitmask (Gast)


Lesenswert?

Karl der Käfer schrieb:
> Im Code? ;-)

Ja, Source- Code!
Willst du Rosinen zählen? :-(((

Wie du ja jetzt selbst erkennst, ist die << Schreibweise eine schlechte 
Variante. ;-)

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> Karl der Käfer schrieb:
>> Im Code? ;-)
>
> Ja, Source- Code!
> Willst du Rosinen zählen? :-(((
Nee, Erbsen :-)
Aber wenn es in den Kran passt, lassen wir eben den Unterschied zwischen 
"Code" und "Souce-Code" weg.

bitmask schrieb:
> Und wenn ich die nicht benötigten Bits unbedingt als
> Kommentar möchte, dann kommentiere ich sie aus. :-D
Und das vergrößert die Source-Datei nicht?
>
> Wie du ja jetzt selbst erkennst, ist die << Schreibweise eine schlechte
> Variante. ;-)
Deshalb hat sie sich auch so verbreitet ;-)

von bitmask (Gast)


Lesenswert?

Karl der Käfer schrieb:
> Nee, Erbsen :-)
So liest sich dein inhaltloses Geschreibsel auch. ;(

In meinen Editoren werden Kommentare ausgegrayed und der Fokus liegt auf 
dem (Source-) Code. Benutzt du Notepad? ;-)

Karl der Käfer schrieb:
> Deshalb hat sie sich auch so verbreitet ;-)
Räusper, wo denn ausser bei Atmel?

von Karl der Käfer (Gast)


Lesenswert?

bitmask schrieb:
> Karl der Käfer schrieb:
>> Nee, Erbsen :-)
> So liest sich dein inhaltloses Geschreibsel auch. ;(

Klar, wenn jemand mit einer Meinung daherkommt, die von der eigenen 
Meinung abweicht, muß man die entweder lächerlich machen

bitmask schrieb:
> Ich sach doch, Pappnase. ;-)

oder aber man greift zu Beleidigungen

> So liest sich dein inhaltloses Geschreibsel auch. ;(


Ich denke, dem TO wurden mehrere Antworten auf seine Fragestellung 
gegeben und gleichzeitig auch demonstriert, daß es verschiedene 
Auffassungen gibt.

EOT

von bitmask (Gast)


Lesenswert?

Karl der Käfer schrieb:
> es verschiedene
> Auffassungen gibt

... und schlechten Programmierstil ... ;-)

Ich entschuldige dich durch den avr-begrenzten Horizont. ;-)

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.