mikrocontroller.net

Forum: Compiler & IDEs Struct komplett auslesen


Autor: jibbel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute!

jedes mal, wenn ich nicht mehr weiter gewusst habe, habt ihr mit 
geholfen!

Hoffentlich könnt ihr mir auch jetzt weiterhelfen!

ich habe folgendes struct
struct
  {
    unsigned char e1:1;
    unsigned char e2:1;
    unsigned char d7:1;
    unsigned char d6:1;
    unsigned char d5:1;
    unsigned char d4:1;
    unsigned char rs:1;
    unsigned char rw:1;
  }data;

die einzelnen bits werden im code gesetzt.

Nun will ich aber data auslesen in ein anderes char schreiben!
wie kann ich das machen?

Im Watch-Fenster von Microchips MPLAB wird die der hex-code des struct 
angezeigt, jedoch beim versuch , das struct auszulesen, bricht der 
compiler mit einem error ab.
char text;
text = data;
hier kommt dann die errormeldung:
error: incompatible types in assignment

K.A. was der von mir will!

wie muss ich den code schreiben, damit ich das komplette struct auslesen 
kann?

lg jibbel

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rechnen kann man immer ;-)

#include <stdio.h>

int main()
{
  typedef struct
    {
       unsigned char e1:1;
       unsigned char e2:1;
       unsigned char d7:1;
       unsigned char d6:1;
       unsigned char d5:1;
       unsigned char d4:1;
       unsigned char rs:1;
       unsigned char rw:1;
  } data;
  
  data a;
  unsigned char text;

  a.e1 = 1;
  a.e2 = 0;
  a.d7 = 0;
  a.d6 = 1;
  a.d5 = 0;
  a.d4 = 1;
  a.rs = 1;
  a.rw = 0;
  text = 128*a.e1 + 64*a.e2 + 32*a.d7 + 16*a.d6 +
           8*a.d5 +  4*a.d4 +  2*a.rs +    a.rw;

  printf("text = 0x%x\n", text);
  return 0;
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder die schmutzige und schnelle Variante:
  data a;
  unsigned char text;
  ...
  text = *(unsigned char*)&a;

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> oder die schmutzige und schnelle Variante:
>
>   data a;
>   unsigned char text;
>   ...
>   text = *(unsigned char*)&a;
> 

text = 0x69
text2 = 0x96

Tja, da hab ich wohl die Reihenfolge vertauscht... hätte jetzt gedacht, 
dass ein Bitfield vom höchsten Bit an losgeht anstatt vom niedrigsten.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie trügerisch sind Weiber^H^H^H^H^H^HCompilerherzen!

Autor: jibbel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jungs, ihr seid die besten!
wieder mal habt ihr es geschafft!

lg jibbel

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wo dürfen wir die Rechnung hinschicken?

Autor: Mano Wee (Firma: ---) (manow)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da dein Bitfeld eh 8 Bits groß ist, mach halt ne Union...

sollte eine Alternative zu den vorigen sein (bissl bitgeschupse)
text = (a.e1 << 7) | (a.e2 << 6) | (a.d7 << 5) | (a.d6 << 4) |
          (a.d5 << 3) |  (a.d4 << 2) | (a.rs << 1) | (a.rw << 0);

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso werden hier soviele Bytes verschwendet?! Was haltet ihr von:
typedef union {
  unsigned char byte;
struct
  {
    unsigned e1:1;
    unsigned e2:1;
    unsigned d7:1;
    unsigned d6:1;
    unsigned d5:1;
    unsigned d4:1;
    unsigned rs:1;
    unsigned rw:1;
  }data;
}

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark Brandis schrieb:
> Tja, da hab ich wohl die Reihenfolge vertauscht...

Ja das hängt allgemein davon ab, ob du eine Little Endian oder Big 
Endian Maschine hast. Bei Little Endian steht Bit0 an oberster Stelle 
bei solch einem struct. Sonst genau anders herum.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein, das hat damit nicht direkt zu tun.

Bei little- und big endian unterscheiden sich dann die Reihenfolge,
in der die Bytes der int im Speicher liegen, was nun bei 8 Bit
bzw. 1 Byte so viel wie wenig ausmacht.

Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
die Endianness aussieht.
Ob das jetzt irgendein C-Standard so vorschreibt oder
eine freiwillige Übereinkunft ist, weiß ich nicht.
Hauptsache, es ist so.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: hat 900ss was mit Ducati zu tun?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was haltet ihr von:
>
> typedef union {
>   unsigned char byte;
> struct
>   {
>     unsigned e1:1;
>     unsigned e2:1;
>     unsigned d7:1;
>     unsigned d6:1;
>     unsigned d5:1;
>     unsigned d4:1;
>     unsigned rs:1;
>     unsigned rw:1;
>   }data;
> }

Nichts. Erstens finde ich es umständlich, überall, wo die Struktur 
verwendet wird, ein '.data' anhängen zu müssen, nur weil an einer 
einzigen Stelle das Byte gebraucht wird, zweitens sind unions gar nicht 
dafür gedacht. Das Verhalten ist laut ISO-C undefiniert.

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
> allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
> die Endianness aussieht.

Zumindest im ARM ABI wird die Reihenfolge aber geändert. Entsprechende
Compiler müssen sich daran halten.

Gruß
Marcus

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Nichts. Erstens finde ich es umständlich, überall, wo die Struktur
> verwendet wird, ein '.data' anhängen zu müssen, nur weil an einer
> einzigen Stelle das Byte gebraucht wird, zweitens sind unions gar nicht
> dafür gedacht.

Zumindest sind sie dafür unglaublich praktisch :-) Wenn man dann noch
einen Compiler hat, der per Erweiterung anonymous structs beherrscht
(z.B. GCC, RVCT), dann kann man sich das '.data' sparen.

Gruß
Marcus

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann da nichts praktisches dran finden. Außerdem ist es mit Casts 
besser lesbar, weil man da gleich sieht, was passiert, statt daß 
irgendwo "hintenrum" Typen uminterpretiert werden. Sowas will ich doch 
lieber explizit im Code stehen haben. Dazu kommt dann noch das Problem 
mit der ISO-Konformität und Portabilität. Deshalb verstehe ich nicht, 
wieso die union-Methode so weit verbreitet und so populär ist.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Portabler oder ISO-konformer ist meine Zeigervariante
auch nicht. Nur viel kürzer.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> nein, das hat damit nicht direkt zu tun.
>
> Bei little- und big endian unterscheiden sich dann die Reihenfolge,
> in der die Bytes der int im Speicher liegen, was nun bei 8 Bit
> bzw. 1 Byte so viel wie wenig ausmacht.
>
> Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
> allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
> die Endianness aussieht.

Ich weiß wenigstens 2 Compiler (für big endian CPUs) bei denen die 
Bitfelder genau anders herum angelegt werden (innerhalb eines Bytes) als 
z.B. bei MS C-Compiler (VS6). Ob das allerdings den Compilerherstellern 
überlassen wird, das weiß ich nicht.
struct bert
{
  int bit_a : 1;
  int bit_b : 1;
  int bits  : 30;
}

bei MS-C kommt beim setzen von bit_a ein 0x00000001 heraus. Bei den 
Compilern der Big Endian CPUs (die ich kenne) kommt 0x80000000 heraus.

Klaus Wachtler schrieb:
> BTW: hat 900ss was mit Ducati zu tun?

Ja, aber Bj. 81. Die haben noch einen schönen Sound. Da fallen die 
morschen Äste aus den Bäumen, wenn du durch einen Wald fährst ;-)

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Portabler oder ISO-konformer ist meine Zeigervariante
> auch nicht.

Doch.  Naja, portabel ist es ja sowieso nicht, aber unions sind da nur 
noch ein weiterer Faktor, den man beachten muß.
ISO-konform ist es aber im Gegensatz zu den unions.

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.