Einzelne bytes zu einem 32 bit Datentypen konvertieren

Gast #6624271
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
Gast #6624288
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?
Gast #6624293
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]
#6624294
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.
#6624298
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
Gast #6624299
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...
Gast #6624350
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren