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
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; |
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.
>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;
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!
Ich würde das ganz ohne Schiebereien machen mit einer Union: Einziger Nachteil: nicht ohne Prüfung auf andere Systeme (Endianess) übertragbar. Vorteil: sehr schnell und kompakt z.B. Beitrag "Re: 3 bytes in einen Datentyp" Was lernen wir daraus: zuerst suchen, dann fragen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.