Forum: Mikrocontroller und Digitale Elektronik Bitweise Verknüpfungen - verschiedene Schreibweisen


von F. F. (foldi)


Lesenswert?

Hallo Leute,

für euch sicher ein Klacks, aber ich habe schon verschiedene 
Schreibweisen für die bitweise Verknüpfungen gesehen.

Gerade bei mehreren Pins finde ich keine richtigen Beispiel.

Gemeint ist das bei C.


Gerade beim Invertieren von mehreren Pins würde ich gern die einfachste 
Schreibweise wissen.

Ist es so die gebräuchlichste Weise?
1
MCUCR  &= ~  ((1<<ISC00)  |  (1<<ISC01));

von g457 (Gast)


Lesenswert?

Sofern verfügbar (sonst selbst definieren) verbessert _BV(x) statt 
(1<<x) die Lesbarkeit.

von Falk B. (falk)


Lesenswert?


von F. F. (foldi)


Lesenswert?

g457 schrieb:
> Sofern verfügbar (sonst selbst definieren) verbessert _BV(x) statt
> (1<<x) die Lesbarkeit.

Hatte ich auch schon mal versucht, führte aber zu Fehlern in Atmel 
Studio.
Da ich da noch andere Probleme hatte, lies ich das weg.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Geschmackssache. Was soll an _BV besser sein? Das läuft für mich unter 
Code-Obfuscation :-) Weder kürzer noch besser lesbar oder sonst ein 
Vorteil bringend.

von Wolfgang (Gast)


Lesenswert?

F. Fo schrieb:
> Ist es so die gebräuchlichste Weise?
> MCUCR  &= ~  ((1<<ISC00) | (1<<ISC01));

Damit löscht du die beiden Bits ISC00 und ISC01 in MCUCR.

Mit Bitinvertierung hat das nur manchmal etwas zu tun, nämlich wenn die 
Bits vorher gesetzt waren ;-)

von F. F. (foldi)


Lesenswert?

Johann L. schrieb:
> Geschmackssache. Was soll an _BV besser sein? Das läuft für mich
> unter
> Code-Obfuscation :-) Weder kürzer noch besser lesbar oder sonst ein
> Vorteil bringend.

Ich mache das dann eher so:
1
DDRB  |=    (1<<interrupt_Led)  |  (1<<blink_Led);
2
  DDRB  &= ~  ((1<<interrupt_Line)  |  (1<<PB1)  |  (1<<PB4));
3
  PORTB  |=    (1<<interrupt_Line)  |  (1<<PB1)  |  (1<<PB4);     
4
  PORTB  &= ~  (1<<interrupt_Led);

von F. F. (foldi)


Lesenswert?

Aber die Frage war, welche ist die gebräuchlichste und einfachste 
Schreibweise und insbesondere beim Invertieren?

von F. F. (foldi)


Lesenswert?

So, nun muss ich erstmal weg. Bin mal gespannt auf die zahlreichen 
Vorschläge heute Abend.

von g457 (Gast)


Lesenswert?

> Was soll an _BV besser sein? Das läuft für mich unter Code-Obfuscation
> :-) Weder kürzer noch besser lesbar oder sonst ein Vorteil bringend.

Hindert Anfänger und n00bs daran sowas in der Art
   x |= (0 << y);
zu versuchen (sieht man regelmäßig in Fehlersuchanfragen hier im Forum). 
Noch schlimmer (ebenfalls effektiv unterbunden und ebenfalls häufig zu 
sehen als Fehler):
   x |= (2 << y);
denn das setzt z.B. effektiv ISC01 statt ISC00. Das trägt beides 
∗erheblich∗ zur Lesbarkeit (und verringerter Code-Obfuscation) bei :-)

YMMV

> So, nun muss ich erstmal weg. Bin mal gespannt auf die zahlreichen
> Vorschläge heute Abend.

Du willst den anstehenden Flamewar verpassen?

von Axel S. (a-za-z0-9)


Lesenswert?

F. Fo schrieb:
> Aber die Frage war, welche ist die gebräuchlichste

Die gibt es nicht. Bzw. sie variiert, je nachdem aus welchen Quellen der 
betrachtete Code stammt.

> und einfachste Schreibweise

Genauso wie Schönheit liegt auch Einfachheit im Auge des Betrachters.

> und insbesondere beim Invertieren?

Vom Invertieren hat bis jetzt noch gar niemand gesprochen. Für mich 
ist die lesbarste Formulierung in C die Verwendung des XOR-Operators:

1
PORTA ^= _BV(LED_STATUS)

allerdings ist der erzeugte Code nicht immer optimal bzw. kann 
unerwünschte Seiteneffekte haben (er wird als read-modify-write 
ausgeführt). Wenn man den Zustand des Bits schon kennt, kann es
sinnvoll sein das Bit per if/else zu setzen bzw. zu löschen.

Schließlich erlauben aktuelle AVRs auch das Invertieren eines Bits im 
PORTx Register, indem man eine 1 ins zugehörige Bit des PINx Registers 
schreibt. Als Alternative zu obigem also:

1
PINA |= _BV(LED_STATUS)


XL

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

F. Fo schrieb:
> Ist es so die gebräuchlichste Weise?
>
1
> MCUCR  &= ~  ((1<<ISC00)  |  (1<<ISC01));

Ich glaub, das ist gebräuchlich. Mir gefällts aber nicht, ich halte 
nichts von überflüssigen Klammern. Deswegen schreib ich es eher so:
1
MCUCR&= ~(1<<ISC00 | 1<<ISC01);
Für mich ist das besser lesbar. Ich würde ja auch nicht "(2*3)+4" 
schreiben, sondern "2*3+4".

von keep simple (Gast)


Lesenswert?

Die Shift Variante ist typisch für Atmels AVR.

In anderen Umgebungen werden die Bits mit ihrer Wertigkeit belegt. Das 
macht auch bei SFR Konfiguration mehr Sinn.
1
#define TIMER_DIFF 0x02
2
#define TIMER_DIR  0x80
3
4
...
5
timercfg |= TIMER_DIR | TIMER_DIFF;

Wenn hier 4 oder mehr Bits konfiguriert werden, gibt das mit dem '<<' 
eine lange und unübersichtliche Zeile. Einfach ausprobieren und selbst 
entscheiden.

von F. F. (foldi)


Lesenswert?

So, nun bin ich wieder zu Hause und lese eure Vorschläge.

Vielen Dank an alle. Als ich den Thread öffnete, da dachte ich es wird 
ein Glaubenskrieg entfacht, aber der ist ausgeblieben.

Von Markus und von keep smile die Schreibweisen gefallen mir am besten.

Was noch als Frage offen bleibt, erkennt der Compiler alle Schreibweisen 
als richtig?
Ganz im Anfang von Visual Basic hatte ich damit einiges in Datenbanken 
gemacht und wehe du hattest da auch nur ne Kleinigkeit nicht genau so 
gemacht, wie es der Compiler erwartete.
Dieses _BV wollte Atmel Studio bei mir ja auch nicht so erkennen.
Vielleicht fehlt ja noch etwas?

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

F. Fo schrieb:
> Was noch als Frage offen bleibt, erkennt der Compiler alle Schreibweisen
> als richtig?

Soweit ich weiß, ist die Reihenfolge bei C genormt und sollte – 
hoffentlich – vom Compiler beachtet werden.

http://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t

Bei Atmel wird meistens nicht mit Bitmasken gearbeitet, aber du kannst 
das trotzdem machen:

1
#define ISC00_M (1<<ISC00)
2
#define ISC01_M (1<<ISC01)
3
4
MCUCR&= ~(ISC00_M | ISC01_M);

Es geht dann auch ohne Klammern, wenn man den Not-Operator "~" getrennt 
anwendet:

1
MCUCR&= ~ISC00_M & ~ISC01_M;

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.