Forum: Mikrocontroller und Digitale Elektronik seriellen Puffer in Struktur laden


von Michael_SS (Gast)


Lesenswert?

Hallo zusammen.

Ich möchte den Inhalt meines seriellen Puffers (wurde gefüllt mit 
diversen Messwerten unterschiedlichen Datentyps) in einer Struktur 
abspeichern:
1
byte SerBuffer1[SER_BUFFER_SIZE];          Definition serieller Puffer
2
3
struct MV {                       // 16 Byte
4
            unsigned char History;
5
            long int Time;
6
            int Temperature;
7
            unsigned char ErrorFlags;
8
            unsigned char Status;
9
            unsigned char Mode;
10
            unsigned int V[3];             // insgesamt 16 Byte
11
         };                                // Array measuring values
12
13
struct MV MeasValues;
Nach dem Emfangen meines Frames ist der serielle Puffer gefüllt. Da ich 
jetzt den aufwendigen Zusammenbau der Mehr-Byte Variablen über 
Zwischenvariablen und Schieben vermeiden möchte, mache ich eine Pointer 
Zuweisung:

void Save_MeasValues()
{
 struct MV *Pt;                      // Zeiger auf MeasValues
 Pt     = &SerBuffer1[4];            // Zeiger laden
 MeasValues = *Pt;                   // MeasValues setzen
 return;
}


Leider bringt mir mein Copiler folgende Fehlermeldung:

Error: ....ation.c(146): a value of type 'byte *' can't be assigned to 
an entity of type 'struct MV *'

Ich verstehe nicht wo das Problem liegt.
Wenn meine Funktion nicht funktioniert, wie sollte ich es denn sonst 
realisieren?

Kann mir jemand weiter helfen?

von Cyblord -. (cyblord)


Lesenswert?

CAST ist das Zauberwort.
Den Pointer auf den Typ des structs casten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael_SS schrieb:
> Ich möchte den Inhalt meines seriellen Puffers (wurde gefüllt mit
> diversen Messwerten unterschiedlichen Datentyps) in einer Struktur
> abspeichern:
> MeasValues = *Pt; // MeasValues setzen
Mal angenommen, du würdest C programmieren und nicht C++, dann geht es 
nicht, dass du da einfach nur angibst "A = B". Sondern du musst sagen: 
kopiere mir den Inhalt der Struktur von hier nach da. Dafür gibt es 
dann sowas wie memcpy() ...

BTW: mach doch um deinen Sourcecode die passenden Tokens
1
[c]
2
  dein C-Code
3
[/c]

von Michael_SS (Gast)


Lesenswert?

cyblord ---- schrieb:
> CAST ist das Zauberwort.
> Den Pointer auf den Typ des structs casten.

Meinst Du so?

void Save_MeasValues()
{
 struct MV *Pt;                      // Zeiger auf MeasValues
 Pt     =(struct MV) &SerBuffer1[4];            // Zeiger laden
 MeasValues = *Pt;                   // MeasValues setzen
 return;
}

von Michael_SS (Gast)


Lesenswert?

Sorry hatte vergessen zu erwähne, dass ich in C programmiere auf dem 
Codevision Compiler.....

von Karl H. (kbuchegg)


Lesenswert?

Michael_SS schrieb:

>  struct MV *Pt;                      // Zeiger auf MeasValues
>  Pt     =(struct MV) &SerBuffer1[4];            // Zeiger laden

(struct MV*)

du veränderst ja den Datentyp des Pointers und nicht die Daten selber

Die ZWischenvariable brauchst du allerdings gar nicht
1
  MeasValues = *(struct MV*)&SerBuffer1[4];

dem Compiler teilst du im Grunde damit mit:
Ich weiss schon, dass rein formal die Speicheradresse SerBuffer1[4] 
legiglich auf ein byte zeigt. Aber lass uns mal so tun, als ob an dieser 
Speicheradresse ein struct MV beginnen würde, die Speicheradresse also 
die Adresse eines struct MV wäre. Daher (struct MV*)

von Michael_SS (Gast)


Lesenswert?

Danke für die Erläuterung. Habe es jetzt verstanden.
Und Danke für die Hilfe. Es funktioniert jetzt.

von Bronco (Gast)


Lesenswert?

Ein kleiner Tip am Rande:
Falls Du zwischen zwei unterschiedlichen Systemen kommunizierst (z.B. 
Microcontroller und PC), wirst Du nicht umhinkommen, Dir genauer 
anzuschauen, wie die Struktur vom C-Compiler im Speicher abgelegt wird.
1
struct MV {                    
2
            unsigned char History;
3
            long int Time;
4
            int Temperature;
5
            unsigned char ErrorFlags;
6
            unsigned char Status;
7
            unsigned char Mode;
8
            unsigned int V[3];             // insgesamt 16 Byte
9
         };                                // Array measuring values

Ein 16Bit- oder 32Bit-Prozessor wird eine solche Struktur nämlich nicht 
ohne weiteres in 16 Bytes ablegen.
Stichworte:
Padbytes, #pragma pack und Endianness
http://en.wikipedia.org/wiki/Data_structure_alignment
http://de.wikipedia.org/wiki/Byte-Reihenfolge

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> MeasValues = *(struct MV*)&SerBuffer1[4];
Und was passiert dann hier mit dem Speicherplatz, den MeasValues ja 
tatsächlich reserviert hat? Es ist doch sinnlos, einen Zeiger von 
"seinem" Struct wegzudrehen. Ich würde dann eher sowas machen:
1
struct MV *MeasValues;

Oder habe ich vor lauter VHDL hier jetzt eine Entwicklung bei C 
verpennt?

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:
> Karl Heinz schrieb:
>> MeasValues = *(struct MV*)&SerBuffer1[4];
> Und was passiert dann hier mit dem Speicherplatz, den MeasValues ja
> tatsächlich reserviert hat?

?

Was soll mit dem Speicher passieren? Er wird mit dem neuen Inhalt 
überschrieben

> Es ist doch sinnlos, einen Zeiger von
> "seinem" Struct wegzudrehen.

Macht doch keiner.
Das ist eine ganz normale Strukturzuweisung

  a = b;

bei der a mit dem Inhalt von b überschrieben wird.

> Oder habe ich vor lauter VHDL hier jetzt eine Entwicklung bei C verpennt?
Das muss aber dann schon lange her sein.
Um Ur-K&R gab es tatsächlich keine Zuweisbarkeit von Strukturobjekten. 
Das war aber nicht besonders praktisch und daher hat man das recht bald 
geändert. Damals schrieb man allerdings auch noch =- und nicht -=

Tatsächlich denke ich:
Rutsch mal ein Stück zur Seite. Die stehst gerade auf der Leitung. (Ist 
nicht bös gemeint). Oder hast du den Dereferenzier-* in
1
  ....   =   *     (struct MV*)&SerBuffer1[4];
2
            ####
nicht gesehen?

von Bronco (Gast)


Lesenswert?

1
MeasValues = *(struct MV*)&SerBuffer1[4];
macht das gleiche wie
1
memcpy( &MeasValues, &SerBuffer1[4], sizeof(struct MV) );

Wie Karl-Heinz schon sagt, kann man "inzwischen" auch in C Strukturen 
durch simple Zuweisung kopieren.

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.