Forum: Compiler & IDEs unklarheit mit Bytevariable


von Sebastian (Gast)


Lesenswert?

Ich bin gerade dabei das Tutorial aus diesem Thread durchzuarbeiten ( 
http://www.mikrocontroller.net/forum-extern/read-2-12770.html).
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

von Sebastian (Gast)


Lesenswert?

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

ich meinte natürlich 2 Bit und nicht Byte

von Christian Schifferle (Gast)


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.

von Christian Schifferle (Gast)


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

von Peter D. (peda)


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

von Notker (Gast)


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/ToolFiles/240/DN_008.pdf

>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

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.