AVR-GCC: warum eigentlich _BV verwenden?

Gast #3376998
Lesenswert?

Neulich bin ich in einem Quelltext über die Verwendung von _BV 
gestolpert, einem Präprozessor-Macro, das aus einer Pin-Nr. per shift 
die entsprechende Bitmaske zaubert, wie ich durch googeln herausgefunden 
habe, also etwa so:
1
# define LED_PIN 3
2

3
...
4

5
PORTx |= _BV(LED_PIN);

In dem Artikel wurde behauptet, dass es empfehlenswert ist, die Pins 
zunächst direkt per Nummerierung zu definieren und dann eben _BV zu 
verwenden. Allerdings wurde nicht begründet warum.
Ich mach das bisher immer so:
1
#define LED_PIN 0b00001000
2

3
...
4

5
PORTx |= LED_PIN;
für mich erschliesst sich der Grund nicht, was an der Version oben 
besser sein soll. Gibt es einen triftigen Grund, oder ist das am Ende 
einfach nur Geschmackssache?
#3377010
Lesenswert?

Hallo,

Ich könnte mir vorstellen, dass _BV(x) das selbe macht, wie (1 << x).

Deine Variante mit der Darstellung eines ganzen Bytes entspricht dabei 
auch der Schreibweise (1<<3), aber (1<<3) ist etwas besser zu lesen als 
00001000, vor allem kann man sich weniger verschreiben, da eine 
vergessene 0 zu einem anderen Ergebnis fürhren kann als gewollt.
Gast #3385015
Lesenswert?

genau: _BV produziert mittels Verschieberei aus der Nummer des Bits die 
entsprechende Maske.

Selber hab ich bisher dazu tendiert zu denken, es ist am Ende 
Geschmackssache, wie man das handhabt. Bis ich heute beim programmieren 
drüber gestolpert bin, dass das ganze vorgefertigte Zeugs in AVR-GCC 
eben mit Pin-Nummern als symbolische Namen arbeitet, die man dann noch 
per shift zu Masken umwandeln muss. Wenn man es mit eigenen Konstrukten 
auf die andere Art angeht und beide Vorgehensweisen im Projekt 
vermischt, kommt man schnell in Teufels Küche...
#3385058
Lesenswert?

Diese Headerdateien sind halt schon ein bisschen älter. Bei den XMegas 
werden in der Regel beides definiert, die Nummer UND eine Bitmask.

Das könntest du ja übernehmen in der Form
1
#define LED_PIN     3
2
#define LED_PIN_bm (1<<LED_PIN)

Die Nummer ist sicher nützlich, wenn es ums shiften geht, sollte man 
also idR auch definieren.
Gast #3388537
Lesenswert?

Die Bitnummern statt Masken kommen aus dem Assemblerbereich: der AVR hat 
eigene Befehle um einzelne Bits in den Portregistern zu setzen und zu 
löschen. Im Assemblerquelltext muß man dazu die Bitnummer angeben, also 
sind die Bits im Headerfile mit ihrer Nummer (anstatt Maske) definiert.
Wenn man jetzt das gleiche Headerfile auch für C verwenden will, geht 
die Bitschieberei los, weil C mit Bitnummern direkt nichts anfangen 
kann. _BV ist eine Möglichkeit, diese Schiebeoperation, die ja mit dem 
Programm nichts zu tun hat und auch nicht wirklich stattfindet, zu 
verstecken, damit der Quelltext übersichtlicher wird.

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