Forum: Mikrocontroller und Digitale Elektronik Einzelne bytes zu einem 32 bit Datentypen konvertieren


von Bitschubser (Gast)


Lesenswert?

Guten Abend zusammen,

ich habe hier einen ADC der mir Daten liefert, aber ich habe keine 
Ahnung, wie ich die einzelnen Bytes zu einem 32 bit Datentypen 
zusammenfasse.

Laut Datenblatt kommen die Daten vom ADC im Format "24 bits, shifted 
left by 4 bits and sign extended to 32 bits"

Wäre super wenn mir jemand auf die Sprünge helfen kann, wie ich das 
folgende Array zu einen int32_t unter Beachtung der oben genannten Regel 
konvertieren kann.
1
uint8_t from_adc[4];

Liebe Grüße
Georg

von Oliver S. (oliverso)


Lesenswert?

1
 int32_t adcVal = ADC;

Oliver

von Bitschubser (Gast)


Lesenswert?

Oliver S. schrieb:
> int32_t adcVal = ADC;

So einfach geht das leider nicht, damit bekomme ich nur unplausible 
Werte

von Andre (Gast)


Lesenswert?

Oliver S. schrieb:
> int32_t adcVal = ADC;

Das klappt aber nur wenn die Bytes in der richtigen Reihenfolge und 
lückenlos im Array liegen.
Ich würde die manuell shiften und oder-verknüpfen.
Außerdem fehlt dann noch ein 4 Bit Shift und die Sign extension.

@Bitschubser welcher ADC ist das genau? Gibt es da eine Tabelle mit 
Beispielwerten?

von Andre (Gast)


Lesenswert?

Google liefert zuverlässig :)

https://ez.analog.com/energy-metering/f/q-a/542312/convert-the-waveform-buffer-output-from-ade9000-to-real-world-values/409886

> volt = [4 extended sign bits]:[24bit data]:[0000] * V constant

von Bitschubser (Gast)


Lesenswert?

Andre schrieb:
> Bitschubser welcher ADC ist das genau?

Ein ADE9000 von Analog Devices

Andre schrieb:
> Gibt es da eine Tabelle mit
> Beispielwerten?

Leider nicht

Andre schrieb:
> Außerdem fehlt dann noch ein 4 Bit Shift und die Sign extension.

Genau davon habe ich keine Ahnung...

Andre schrieb:
> Das klappt aber nur wenn die Bytes in der richtigen Reihenfolge und
> lückenlos im Array liegen

Normale 32 bit Werte vom ADC bekomme ich woe folgt konvertiert:
1
int32_t data = (from_adc[1] << 24) + (from_adc[0] << 16) + (from_adc[3] << 8) + from_adc[2]

von Falk B. (falk)


Lesenswert?

Bitschubser schrieb:
> Laut Datenblatt kommen die Daten vom ADC im Format "24 bits, shifted
> left by 4 bits and sign extended to 32 bits"
>
> Wäre super wenn mir jemand auf die Sprünge helfen kann, wie ich das
> folgende Array zu einen int32_t unter Beachtung der oben genannten Regel
> konvertieren kann.
1
uint8_t from_adc[4];
2
int32_t long_adc;
3
4
long_adc = (uint32_t)from_adc[3]<<24 |
5
           (uint32_t)from_adc[2]<<16 |
6
           (uint32_t)from_adc[1]<<8 |
7
           (uint32_t)from_adc[0];
8
9
long_adc >>= 4;

Die Reihenfolge der einzelnen Bytes kann auch umgekehrt sein, muss man 
passend machen.

von Sebastian W. (wangnick)


Lesenswert?

Bitschubser schrieb:
> "24 bits, shifted left by 4 bits and sign extended to 32 bits"

Danach müsstest du den Wert (als int32_t) einfach um 4 Bitstellen nach 
rechts zurückschieben können um den gemessenen 24-Bit-Wert zu erhalten.

Zumindest wenn dein Compiler "Arithmetic Right Shift" implementiert. 
Ansonsten noch nach dem >> mit 0xF0000000 verodern.

Bitschubser schrieb:
> uint8_t from_adc[4];

Dazu müsste man noch die Wertigkeit der Bytes kennen. Was sagt das 
Datenblatt denn zur Byte-Reihenfolge (most significant / least 
significant)?

LG, Sebastian

von c-hater (Gast)


Lesenswert?

Bitschubser schrieb:

> ich habe hier einen ADC der mir Daten liefert, aber ich habe keine
> Ahnung, wie ich die einzelnen Bytes zu einem 32 bit Datentypen
> zusammenfasse.

Ich auch nicht.

> Laut Datenblatt kommen die Daten vom ADC im Format "24 bits, shifted
> left by 4 bits and sign extended to 32 bits"

Nett, aber die entscheidende Information fehlt: die "Byte-Order". Kommt 
der Scheiß big-endian oder little-endian?

Natürlich würde man das leicht selbst herausbekommen können, allein 
daran, in welchen Bytes es bei konstanter Messgröße immer noch gar 
furchtbar oder schon nicht mehr ganz so schlimm oder auch garnicht mehr 
wackelt. Aber dazu müßte "man" wenigstens andeutungsweise eigenständig 
denken können...

von J. -. (Gast)


Lesenswert?

Variante mit einer union
1
union{
2
  int32_t dword;
3
  uint8_t byte[4];
4
}dwb;
5
6
for(uint8_t i=0;i<4;i++) dwb.byte[i] = adc[i];
7
adc32=dwb.dword >> 4;
Ob das Vorzeichen dann tatsächlich korrekt ist, weiß ich nicht. Und die 
Byte-Reihenfolge muß man noch anpassen, wie die Vorgänger bereits 
schruben.

von MaWin (Gast)


Lesenswert?

Jürgen S. schrieb:
> Variante mit einer union

... ist ein cast, also besser als cast schreiben.

von MaWin (Gast)


Lesenswert?

edit:
Hatten wir hier die Tage erst, ist schlechter Stil mit der union.

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.