3 byte zu 24 bit

Gast #871783
Lesenswert?

Hallo zusammen,


ich lese mit einem MSP430F2232 über SPI einen analogen Spannungswert 
ein, der mit einem 24 bit AD-Wandler gemessen wurde.
Der AD-Wandler schickt nach Anfrage des Wertes 3 Bytes (Most 
significant-, Mid - und Least significant Byte). Zusammen also meine 24 
bit.
Mein Problem ist, ich weiß nicht (bin Anfänger), wie ich aus den 3 Bytes 
nun den Spannungsbetrag mache.

Im Moment versuche ich es mit folgendem Code (ich nutze IAR Kickstart):
 "ADS_RXTX(command);                       //send command
  value1=ADS_RXTX(0x00);                   //send clock
  value2=ADS_RXTX(0x00);                   //send clock
  value3=ADS_RXTX(0x00);                   //send clock

 big=value2 | (value3<<8) | ((unsigned long)value4<<16);"

"ADS_RXTX()" sendet die Anfrage an den AD-Wandler und gibt den Wert vom 
AD-Wandler zurück. "0x00" soll dann keine Nachricht schicken, sondern 
nur eine clock erzeugen, damit der AD-Wandler seine Werte schicken kann. 
Die 3 Bytes lege ich dann also in den Variablen value1, value2 und 
value3 (alle als "unsigned char" deklariert). Z.B. kommen dann folgende 
Werte in den Variablen vor:
value1: 0x18
value2: 0xFE
value3: 0x71

Daraus hätte ich gerne in der Variable big (deklariert als "unsigned 
long") den dezimalen Wert. Hier also 18FE71hex=1638001dec.

Hat jemand eine idee, wies funktioniert?


Vielen Dank,
Björn
#871788
Lesenswert?

1
long big;
2
unsigned char value1,value2,value3;
3
...
4
...
5
ADS_RXTX(command);                       //send command
6
value1=ADS_RXTX(0x00);                   //send clock
7
value2=ADS_RXTX(0x00);                   //send clock
8
value3=ADS_RXTX(0x00);                   //send clock
9

10
big = (value1<<16) | (value2<<8) | value3;
Geht zumindest bei mir.
evtl. auch noch etwas zur Sicherheit Casten
1
big = (unsigned long)(value1<<16) | (unsigned int)(value2<<8) | value3;
#871796
Lesenswert?

Timmo H. wrote:
> evtl. auch noch etwas zur Sicherheit Casten
>
1
> big = (unsigned long)(value1<<16) | (unsigned int)(value2<<8) | value3;
2
>
Der erste cast ist bei einer 8- oder 16-Bit-Plattform i.d.R. immer 
erforderlich (bei allen Plattformen, in denen int nur 16 Bit lang 
ist), da das Schieben um 16 Stellen sonst ins Nirvana geht. Der zweite 
cast ist sinnvoll (ein einfaches unsigned dürfte aber reichen), da bei 
Schiebeoperationen bei signed-Werten die Vorzeichenbehandlung nicht 
festgelegt ist.
#871799
Lesenswert?

holger wrote:
>>big = (unsigned long)(value1<<16) | (unsigned int)(value2<<8) | value3;
>
> Ich würde das so machen
>
> big = ((unsigned long)value1<<16) | ((unsigned int)value2<<8) | value3;
Da hast Du völlig Recht! Ich hatte die falsche Klammerung oben glatt 
übersehen. Die Werte müssen natürlich vor dem Schieben konvertiert 
werden!

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