mikrocontroller.net

Forum: Compiler & IDEs unklarheit mit Bytevariable


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin gerade dabei das Tutorial aus diesem Thread durchzuarbeiten ( 
http://www.mikrocontroller.net/forum-extern/read-2...).
Nur dort kommt mir etwas nicht ganz logisch vor. Und zwar steht da, um 
auf jedes Einzelne Bit in einem Register zugreifen zu können, erstellt 
man eine Bytevariable die so aussieht:

struct {
    unsigned char bStatus_1:1;    // 1 Bit für bStatus_1
    unsigned char bStatus_2:1;    // 1 Bit für bStatus_2
    unsigned char bNochNBit:1;    // Und hier noch mal ein Bit
    unsigned char b2Bits;         // Dieses Feld ist 2 Bits breit
    // All das hat in einer einzigen Byte-Variable Platz.
    // die 3 verbleibenden Bits bleiben ungenutzt
} x;


Nur unklar ist mir jetzt, warum die Varieble b2Bits 2 Byte groß sein 
soll. Wenn der Code so lauten würde, wäre das einleuchtend:

    unsignet char b2Bits:2;

Oder ist dies ein Fehler im Tutorial?

Ich hoffe, dass der Quellcode hier noch einigermaßen gut leserlich 
abgebildet ist.

M.f.G. Sebastian

www.Roboter-Elektronik.de

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
: Nur unklar ist mir jetzt, warum die Varieble b2Bits 2 Byte groß sein 
soll

ich meinte natürlich 2 Bit und nicht Byte

Autor: Christian Schifferle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut aufgepasst Sebastian, gratuliere ;-)

Du hast natürlich recht. Es müsste heissen
unsigned char b2Bits:2;

Danke für den Hinweis und herzliche Grüsse
Christian

P.S. ob die ganze Variable x nun 8 oder 16 Bit breit ist hängt vom 
Compiler ab. Da normalerweise Bitfelder auf integer-Grösse ausgerichtet 
werden könnte ich mir durchaus vorstellen, dass x auch 16 Bit sein 
könnte, dann blieben allerdings 11 Bits ungenutzt (muss ich mal 
ausprobieren). Ich hoffe, AVR-GCC ist hier schlau genug, auf 8 Bit 
auszurichten.

Autor: Christian Schifferle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab's grade mal eben ausprobiert.

AVR-GCC richtet tatsächlich auf 8 Bit aus. Dies bedeutet, die Variable x 
ist 8 Bits breit und es verbleiben 3 Bits ungenutzt.

Gruss
Christian

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achtung !


Der ANSI-C-Standard definiert aber nicht, in welcher Reihenfolge die 
Bitfelder in ein Byte gepackt werden !


Wenn man z.B. dieses Byte vom AVR über die UART zum PC überträgt und 
dort auch ein C-Programm dieselbe Bitfelddefinition verwendet, heißt das 
noch lange nicht, das die Bits dort auch wieder an der gleichen Stelle 
sind.

Bzw. mit dem einen Compiler könnte es klappen, mit einem anderen aber 
nicht.


Deshalb sollte man Bitfelder nur dort verwenden, wo die Reihenfolge 
keine Rolle spielt.
Z.B. auf keinen Fall, wenn dieses Byte z.B. auf einem Port ausgegeben 
werden soll und jedes Bit einem genau definiertem Pin entsprechen muß.


Ich habe mir angewöhnt, die Position von Bits über AND- und 
OR-Operationen eindeutig festzulegen.
Z.B. setze Bit 5:
var |= 1<<5;

Letztendlich macht der Compiler ja auch nichts anderes bei den 
Bitfelderzugriffen.


Peter

Autor: Notker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der ANSI-C-Standard definiert aber nicht, in welcher Reihenfolge die Bitfelder 
in ein Byte gepackt werden !

Doch, nämlich in aufsteigender Wertigkeit. Es ist lediglich davon 
abhängig, ob man sich auf einem little-endian oder einem big-endian 
System befindet. Ich denke, dies wurde in diesem Forum aber schon einmal 
durchgekaut. Aber selbst wenn man dies nicht weiss, kann man es einfach 
ausprobieren.


>Deshalb sollte man Bitfelder nur dort verwenden, wo die Reihenfolge keine Rolle 
spielt.
>Z.B. auf keinen Fall, wenn dieses Byte z.B. auf einem Port ausgegeben werden soll 
und jedes Bit einem genau definiertem Pin entsprechen muß.


Das ist ist kompletter Quatsch! Im Gegenteil, Bitfelder sind nämlich in 
C u.a. genau für diese Sache gedacht und geeignet! Siehe z.B. 
"Programming of Embedded Systems in C and C++" vom O'Reilly Verlag. Wie 
schon gesagt, die Reihenfolge ermittelt man einmal durch einen Versuch 
und kann dann wunderbar damit arbeiten. Es gibt hierzu auch 
Design-Notes, wie z.B. diese hier:

http://www.avrfreaks.net/filednload.php?url=/Tools...

>Ich habe mir angewöhnt, die Position von Bits über AND- und OR-Operationen 
eindeutig festzulegen.
>Z.B. setze Bit 5:
>var |= 1<<5;

Das kannst du halten, wie dir beliebt. Aber deshalb brauchst du anderen 
Leuten nicht einzureden, dass Bitfelder in C ungeeignet sind um 
Portadressen anzusprechen!

meine 0.02$ zu diesem Thema

Notker

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.