www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitfeld in Struct in Union


Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HI,

ich habe eine Frage zum Thema Bitfeld in Struct in Union.

Es geht mir dabei um einen Datentyp bestehend aus 8 Bits, welche man 
entweder gemeinsam oder einzeln ansprechen können soll.

Ich würde in meinem Programm gern folgendes schreiben können:


typedef struct
{
    uint8_t    bit0:1,
               bit1:1,
               bit2:1,
               bit3:1,
               bit4:1,
               bit5:1,
               bit6:1,
               bit7:1,
}meintyp;


void func1 (meintyp a)
{


}


void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a=4;
    a=zahl;
    a.bit0=1;
    a.bit1=1;

    func1(a);
    func1(23);
}



Wie kann ich das lösen?

Wenn ich es so gestalte:


typedef union
{
    uint8_t    byte;
    uint8_t    bit0:1,
               bit1:1,
               bit2:1,
               bit3:1,
               bit4:1,
               bit5:1,
               bit6:1,
               bit7:1,
    }bits;
}meintyp;

dann müsste ich doch:

void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a.byte=4;
    a.byte=zahl;

    a.bit0=1;
    a.bit1=1;

    ....
}

schreiben oder!?

Gruß,
Hannes

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
typedef union
{
  uint8_t    byte;
  struct
  {
    unsigned      bit0:1;
    unsigned      bit1:1;
    unsigned      bit2:1;
    unsigned      bit3:1;
    unsigned      bit4:1;
    unsigned      bit5:1;
    unsigned      bit6:1;
    unsigned      bit7:1;
      };
} meintyp_t;

int main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a.byte=4;
    a.byte=zahl;

    a.bit0=1;
    a.bit1=1;
    return 0;
}

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
unsigned      bit0:1;

Wenn man da das "unsigned" weglässt, nimmt er dann ein Bit fürs 
Vorzeichen? ;-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du unsigned weglässt, geht gar nichts mehr, weil der Typ fehlt.
Lässt du nur das un weg und machst dann folgendes:
    a.bit1=1;
    printf( "%d\n", a.bit1 );
.. kommt das raus:
klaus@i4a:~ > gcc -Wall t.c && ./a.out
-1

Alle gesetzten Bit in einer signed sind offenbar wie üblich -1 :-))

Je nach Fall ist es egal, ein Bit wird man eh nur auf gleich oder 
ungleich 0 testen.
Ein Vergleich mit 1 wird aber lustige Folgen haben.

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
>
> typedef union
> {
>   uint8_t    byte;
>   struct
>   {
>     unsigned      bit0:1;
>     unsigned      bit1:1;
>     unsigned      bit2:1;
>     unsigned      bit3:1;
>     unsigned      bit4:1;
>     unsigned      bit5:1;
>     unsigned      bit6:1;
>     unsigned      bit7:1;
>       };
> } meintyp_t;
> 

Anonyme struct members sind zwar äußerst praktisch, aber leider nicht
standardkonform und werden daher nicht von allen Compilern
unterstützt. GCC und ARM RealView (mit entsprechendem #pragma)
erlauben dieses Konstrukt.

Gruß
Marcus
http://www.doulos.com/arm/

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hallo KLaus,

danke für die Rückmeldung doch mein eigentliches Problem kommt erst 
noch.

@Marcus Harnisch,
das ist in diesem Fall ohne Folge da ich keinen datenaustausch auf 
unterschiedlichen Architekturen ausführen werde und keine 
unterschiedlichen Kompiler nutze, und der Code nur auf einem Prozessor 
laufen wird. Zumal das ganze nur zur internen Verwaltung innerhalb eines 
geschachtelten abgeschlossenen c Objektes zum Einsatz kommt.

1)
fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig? 
oder geht das, weil es eine union ist? das sieht komisch aus.

2)
soweit das ich das schreiben kann:

    uint8_t   zahl=0;
    meintyp_t a;

    a.byte=4;
    a.byte=zahl;

    a.bit0=1;
    a.bit1=1;
    return 0;

war ich schon, nur ich würde das gern so schreiben können:

void func1 (meintyp a)
{


}


void main (void)
{
    uint8_t   zahl=0;
    meintyp_t a;

    a=4;
    a=zahl;
    a.bit0=1;
    a.bit1=1;

    func1(a);
    func1(23);
}

ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion 
diesen typ als übergabetyp hat, dann würde ich sie gern wie oben 
aufgezeigt aufrufen können - geht das?

die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne 
vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast 
schlägt auch fehl...deswegen ja die Geschichte mit der union...

Gruß,
Hannes

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes schrieb:
> ...
> 1)
> fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig?
> oder geht das, weil es eine union ist? das sieht komisch aus.

unsigned ist ein Typ; du kannst auch unsigned int schreiben, wenn dir 
das lieber ist.

signes ist int ebenso wie signed int, und unsigned ist unsigned int, und
short ist short int etc.

>
> 2)
> soweit das ich das schreiben kann:
>
>     uint8_t   zahl=0;
>     meintyp_t a;
>
>     a.byte=4;
>     a.byte=zahl;
>
>     a.bit0=1;
>     a.bit1=1;
>     return 0;
>
> war ich schon, nur ich würde das gern so schreiben können:
>
> void func1 (meintyp a)
> {
>
>
> }
>
>
> void main (void)
> {
>     uint8_t   zahl=0;
>     meintyp_t a;
>
>     a=4;
>     a=zahl;
>     a.bit0=1;
>     a.bit1=1;
>
>     func1(a);
>     func1(23);
> }
>
> ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion
> diesen typ als übergabetyp hat, dann würde ich sie gern wie oben
> aufgezeigt aufrufen können - geht das?

nein.
Bzw. nur mit cast, aber dann kannst du auch .byte schreiben.

>
> die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne
> vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast
> schlägt auch fehl...deswegen ja die Geschichte mit der union...

nicht in C, in C++ geht es mit Überladen von Operatoren..

>
> Gruß,
> Hannes

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> typedef union
> {
>   uint8_t    byte;
>   struct
>   {
>     unsigned      bit0:1;
>     unsigned      bit1:1;
>     unsigned      bit2:1;
>     unsigned      bit3:1;
>     unsigned      bit4:1;
>     unsigned      bit5:1;
>     unsigned      bit6:1;
>     unsigned      bit7:1;
>       };
> } meintyp_t;
>

mach mal ein sizeof(meintyp_t).
Meiner meinung nach sollte da eine 4 rauskommen, auch wenn du prgma pack 
verwendest.
da das bitfeld aller wahrscheinlichkeit 32 bit breit ist.

Autor: aha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Riesenaufwand weil man nicht mit Hex operieren will...

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.