Forum: Mikrocontroller und Digitale Elektronik Struct abspeichern


von Danni (Gast)


Lesenswert?

Guten Abend !

Ich habe ein kleines Problem, und zwar habe ich eine Struktur die aus
diversen Bitfeldern und einem long int besteht und die 8 Byte lange ist
(sizeof). Wie kann ich auf die 8 einzelnen Bytes zugreifen?
Hatte mir überlegt nen Zeiger auf den Anfang der Struktur zu legen und
immer das vom Zeiger addressierte Byte abzuspeichern. Das drauffolgende
Byte  mittels zeiger+sizeof(unsigned char) genauso adressieren.
Geht sowas?
Kann mir jemand da mal mit nem C Codefragment helfen?

Danke

Danni

von Timo (Gast)


Lesenswert?

Hallo Danni,

ich habe einmal kurz ein Codefragment geschrieben. Hoffe, dass keine
Fehler enthalten sind.
Prinzipiell kannst Du aber auch eine Union verwenden.

struct
{
  unsigned int Bit0   : 1;
  unsigned int Bit1_5 : 4;
  long LongVariable;
} Variable;

unsigned char* PointerToLong;

// Pointer auf Long Variable setzen
PointerToLong = &Variable.LongVariable;

// Zugriff auf die einzelnen Elemente
Byte0 = PointerToLong[0];
Byte1 = PointerToLong[1];

von Danni (Gast)


Lesenswert?

Abend !

Danke für die Hilfe aber habe mich leider etwas znglücklich ausgedrückt
und zwar meine ich mal anls Beispiel eine Struktur:

struct
{
unsigned int x:3
unsigned int y:5

*
*

long int k;
} name;

Nehmen wir mal an die Struktur ist so groß, dass diese 8 Byte im
Speicher belegt. Wie bekomme ich Byte0, Byte1 ...  Byte7 einzeln
ausgelesen, so dass ich diese byteweise in ein i2c EEPROM packen kann?

von Steffen (Gast)


Lesenswert?

Hallo Danni!

Wie wärs mit
(*unsigned char)name[0];?

Viele Grüße
Steffen

von Timo (Gast)


Lesenswert?

Hallo,

also probieren wir es noch einmal.
Ich habe sowieso einen cast vergessen.
Hoffentlich habe ich Dein Problem jetzt verstanden.


unsigned char* PointerToStruct;
unsigned charZiel[8];

PointerToStruct = (unsigned char)&name;

for(int i=0; i<8; i++)
  Ziel[i] = *PointerToStruct++;

von Danni (Gast)


Lesenswert?

Hmm werde ich probieren, vielen Dank,

von Timo (Gast)


Lesenswert?

Der cast muss natürlich (unsigned char*) heißen!

von The Daz (Gast)


Lesenswert?

Danni,
definiere dir eine union, die aus deiner Struktur und einem gleich
grossen byte array besteht und fertig.

typedef union
{
   struct
   {
      unsigned int x:3
      unsigned int y:5
      *
      *
      long int k;
   } name;

   unsigned char bytes[8];
} myUnion;

Der Rest ist klar oder (C-Grundlagen).

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

besser;

typedef union
{
   struct
   {
      unsigned int x:3
      unsigned int y:5
      *
      *
      long int k;
   } name;

   unsigned char bytes[sizeof(name)];
} myUnion;

Matthias

von Danni (Gast)


Lesenswert?

Hallo

Danke für die viele Hilfe,
Möchte er gern mit dem struct machen da es vom Programm am besten
passt, sollte eigentlich auch gehen

von Karl heinz B. (heinzi)


Lesenswert?

kannst Du auch.
Du kannst dann trotzdem eine union verwenden:

void WriteToEEprom( struct irgendwas* What )
{
  union {
    struct irgendwas Original;
    unsigned char Bytes[ sizeof( struct irgendwas ) ]
  } *Wandler;

  Wandler = &What;

  for( i = 0; i < sizeof( irgendwas ); ++i )
    WriteByteToEEprom( Wandler->Bytes[i] );
}

Hmm. Wenn ich mir das so anschaue, ist wahrscheinlich
die cast-Loesung doch einfacher:

void WriteToEEprom( struct irgendwas* What )
{
  for( i = 0; i < sizeof( irgendwas ); ++i )
    WriteByteToEEprom( ((unsigned char*)What)[i] );
}

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Was soll denn der ganze Käse?
Einfach per 'eeprom_write_block' die gesamte Struktur ins EEPROM
schreiben...

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

steht in diesem Thread irgendwo was vom AVRGCC?

Matthias

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Das 'eeprom_write_block' sollte nur als Pseudocode dienen, ein
Äquivalent wird es wohl in so ziemlich jedem AVR-C-Compiler geben, oder
etwa nicht?

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

es steht nichtmal was von AVR in diesem Thread :-) Und
eeprom_write_block hilft dir auch nur für interne EEPROM der AVRs. Wenn
du ein externes EEPROM nutzen willst brauchts halt einen eigenen Code.
Und da muss Danni wissen wie er eine Struktur als Array von chars
behandeln kann. Und genau darum ging es hier. Mir (und aller
Wahrscheinlichkeit nach auch dir) ist natürlich klar das man da einfach
hingeht und sowas
1
//Schreibt einen Datenblock ab src mit Länge length ins EEPROM ab dst
2
bool eepromWriteBlock(void * src, void * dst, size_t length)
3
{
4
    uint8_t * lsrc = src;    
5
    uint8_t * ldst = dst;    
6
    bool res = true;
7
8
    for(size_t i = 0; i < length; i++)
9
    {
10
        res = res && eepromWriteUInt8(src++, dst++);
11
    }
12
13
    return res;
14
}
15
16
void foo(void)
17
{
18
    if(false == eepromWriteBlock(&someGlobalStruct,
19
                                 &structEEPROMLocation,
20
                                 sizeof(someGlobalStruct));
21
    {
22
        printf("The EEPROM .....")
23
    }
24
}

schreibt. Aber ob das für einen Anfänger als Antwort ideal ist?

Matthias

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.