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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.