www.mikrocontroller.net

Forum: Compiler & IDEs 3 byte variable mit 20 + 4 bit


Autor: Philipp Co (ba4_philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte einen seriellen Datenstrom in eine Variable einlesen. Dazu 
benutze ich bis jetzt ein long int. Die Daten die kommen haben 
allerdings nur 24Bit (3Byte). Ausserdem stellen die ersten 20bit eine 
Kennung da und nur die lezten 4 bit sind eigentliche Daten. Ich habe 
bisher mit struct gearbeitet um zB einzelne Bits in einem Byte 
zusammenzufassen, aber wie geht man nun an das Problem mit 20bit heran?

Wenn man in einer struct
unsigned long int id:20
unsigend char data:4

machen würde, werden dann auch nur 3 Byte belegt oder ist es mit einer 
struct ohnehin die falsche Herangehensweise?

Ich würde am Ende gerne die Variable füllen in dem ich beim Anfang der 
Übertrtagung sage:

var = 0;

Dann die 1 setze mit:

var |= 1L << bitnummer;

und am Ende würde ich dann gerne var.id und var.data einzeln auswerten 
können. Kann mir jmd sagen wie man soetwas am geschicktesten 
implementiert?

Vielen Dank
Gruß Philipp

Autor: G. L. (sprintersb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Di kannst dir eine Union bauen:
typedef union
{
   struct 
   {
      unsigned long int id:20;
      unsigend char data:4;
   } val;

   struct
   {
      unsigned bit0:1;
      unsigned bit1:1;
      unsigned bit2:1;
      ...
   } bits;
} data24_t;

und kannst dann drauf zugreifen wie gewünscht:
 data24_t data; 
 if (data.bits.bit0)
    ...
 data.val.id   = 0x12345;
 data.val.data = 5;

Alternativ kannst du Tipparbeit sparen, indem du die erste struct anonym 
machst (kein ANSI, nur noch GNU-C):
typedef union
{
   struct 
   {
      unsigned long int id:20;
      unsigend char data:4;
   };

   struct
   {
      ...
   } bits;
} data24_t;
 data24_t data; 
 if (data.bits.bit0)
    ...
 data.id   = 0x12345;
 data.data = 5;

Sinnvoll ist eine 24-Bit Struktur/Union allerdings nur dann, wenn du 
Arrays davon verwendest bzw. sehr viele Komposite, die ausser dieser 
Struktur noch andere Daten dahinter enthalten. Dies wird dann 
Speicherplatz sparen.

Was den Code-Verbrauch angeht, ist es uU deutlich günstiger, die 
Struktur/Union auf 32 Bit aufzublasen, auch wenn 8 Bit ungenutzt 
bleiben. Grund ist, daß je nach Compiler (zB GCC) 32-Bit-Objkete in 
Registern gehalten werden können, während das für 24-Bit-Objekte 
(allgemein für Objekte, deren Bytegröße keine 2-Potenz ist) nicht in 
Regs gehalten werden und im Frame leben, was Code und Frame kostet.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Variante ist schön schnell, aber auch mit Vorsicht zu genießen, da 
das Ergebnis bei deiner Methode undefiniert ist.

Verlassen würde ich mich erst darauf, wenn du es ausprobiert hast. 
Genormt ist an der Union nur, dass man auf gleichem Wege rauslesen soll, 
wie man auch hereinschreibt. Sonst ist das Ergebnis, wie gesagt, 
undefiniert und damit Compiler, Platform... abhängig.

Autor: Philipp Co (ba4_philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

im Prinzip brauch ich die bits nicht direkt ansprechen und wenn es eh 
auf 4 Byte aufgeblasen werden sollte (sind nicht viele von den 
Variablen, die benöigt werden) dann könnte man es doch auch so machen 
oder:
typedef union
{
   struct 
   {
      unsigned long int id:20;
      unsigend char data:4;
   };
      unsigned long int raw;
} data24_t;

data24_t data; 

Das würde das long int raw Teil ja mit im gleichen Speicher liegen wie 
die struct und ich könnte mit
data24_t data;
data.raw = 0;

data.raw |= 1L << bit;
das ganze Ding auf 0 setzen und dann einzelne bits (also bit) setzen.
Am Ende kann man dann data.id und data.data auslesen oder mache ich da 
einen Denkfehler?

Vielen Dank schonmal
Gruß Philipp

Autor: StinkyWinky (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Georg-johann Lay

Die Struktur aus Deinem Vorschlag benötigt aber doch 5 Byte. Wenn Du 
dann noch ein Array von denen anlegst, wird durch das Alignement wohl 
noch ein bisserl mehr daraus. Kommt natürlich auf die 
Zielsystem-Architektur an.

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.