Forum: Mikrocontroller und Digitale Elektronik Zweierkomplemente zusammenführen


von fliege (Gast)


Lesenswert?

Moin.
Ich möchte einen 32-Bit-Wert, bestehend aus 4 Bytes zusammenführen.

Bei zwei Bytes ist das ja ganz einfach:

Wert = Byte_1 << 8 | Byte_2;

Aber wie geht das jetzt mit 4 Bytes?

von Karl H. (kbuchegg)


Lesenswert?

fliege schrieb:
> Moin.
> Ich möchte einen 32-Bit-Wert, bestehend aus 4 Bytes zusammenführen.
>
> Bei zwei Bytes ist das ja ganz einfach:
>
> Wert = Byte_1 << 8 | Byte_2;
>
> Aber wie geht das jetzt mit 4 Bytes?

Im Prinzip genauso. Man muss nur aufpassen, das man rechtzeitig die 
Kurve zu 32 Bit kriegt.
1
Wert = (uint32_t)Byte_1 << 24 |
2
       (uint32_t)Byte_2 << 16 |
3
       Byte_3 << 8            |
4
       Byte_4;

von fliege (Gast)


Lesenswert?

Warum ist bei Byte 1 und Byte 2 eine Variablendeklaration von uint32t 
vorgesetzt und bei Byte 3 & 4 nicht? Oder war das nicht Absicht?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

fliege schrieb:

> Bei zwei Bytes ist das ja ganz einfach:
> Wert = Byte_1 << 8 | Byte_2;
              ^             ^

Kennst du die Byte-Reihenfolge (Endianess) auf deinem System oder es ist 
zufällig richtig? http://de.wikipedia.org/wiki/Byte-Reihenfolge

In deinem Betreff steht Zweierkomplemente
http://de.wikipedia.org/wiki/Zweierkomplement

Wenn Byte_1, Byte_2... tatsächlich Zahlen mit Vorzeichen sind, dann 
würde ich statt Bitoperationen die Rechenoperationen benutzen und die 
"Optimierung" dem Compiler überlassen.

int8_t Byte_1, Byte_2;
int16_t Wert = Byte_1 * 256 + Byte_2;

von fliege (Gast)


Lesenswert?

Dann habe ich mich vielleicht in der Fragestellung falsch ausgedrückt. 
Die Bytes bekomme ich ine einem CAN-Telegramm und weiß daher welches 
Byte das MSB und welches das LSB ist.

Ich habe B1 B2 B3 B4 wobei B1 das MSB und B4 das LSB ist.

Jetzt brauche ich eine Operation, die mirt aus den vier Bytes einen Wert 
zaubert. (So wie ich das oben mir 2 Bytes beschrieben habe.)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Beitrag "Re: Zweierkomplemente zusammenführen"

"Zweierkomplemente" spielen dann keine Rolle. Du musst aber wissen, 
welchen Datentyp du letztendlich für wert brauchst.

von Karl H. (kbuchegg)


Lesenswert?

fliege schrieb:
> Warum ist bei Byte 1 und Byte 2 eine Variablendeklaration von uint32t
> vorgesetzt und bei Byte 3 & 4 nicht? Oder war das nicht Absicht?

Doch das ist Absicht
1) das ist keine Variablendeklaration sondern ein Cast
2) ist der notwendig, damit ich den Compiler zwinge, die Operation
   in 32 Bit auszuführen.
   Tu ich das nicht, dann macht er eine int Operation (also 16 Bit)
   daraus und dann fällt mir links alles raus.

3) solltest du dir ein C-Buch zulegen

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

fliege schrieb:
> Dann habe ich mich vielleicht in der Fragestellung falsch ausgedrückt.
> Die Bytes bekomme ich ine einem CAN-Telegramm und weiß daher welches
> Byte das MSB und welches das LSB ist.
>
> Ich habe B1 B2 B3 B4 wobei B1 das MSB und B4 das LSB ist.
>
> Jetzt brauche ich eine Operation, die mirt aus den vier Bytes einen Wert
> zaubert. (So wie ich das oben mir 2 Bytes beschrieben habe.)

Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege 
damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Kluchscheißender Kluchscheißer schrieb:

> Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege
> damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.

Geht, aber man muss dann die Prozessor-Byteorder beachten. Vom CAN-Bus 
kommen die vier Bytes mit MSB first. Das kann vielleicht gerade die 
"falsche" Byteorder für den Prozessor sein.

Multiplikation mit 2^24, 2^16, 2^8 und 2^0 und anschließende Addition 
der 4 Werte wäre da schon das portabler, weil dann das Byteordering des 
Prozessors vollkommen egal ist.

Gruß,

Frank

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Frank M. schrieb:
> Kluchscheißender Kluchscheißer schrieb:
>
>> Ich habe zwar keine Ahnung von C, aber wie wäre es mit einer Union? Lege
>> damit 4 Byte-Variablen auf die selbe Adresse wie die 32-Bit-Variable.
>
> Geht, aber man muss dann die Prozessor-Byteorder beachten. Vom CAN-Bus
> kommen die vier Bytes mit MSB first. Das kann vielleicht gerade die
> "falsche" Byteorder für den Prozessor sein.

Naja, ich denke, die kann man vorwärts wie rückwärts in das Array mit 
Bytes legen.

>
> Multiplikation mit 2^24, 2^16, 2^8 und 2^0 und anschließende Addition
> der 4 Werte wäre da schon das portabler, weil dann das Byteordering des
> Prozessors vollkommen egal ist.

Das mag sein, jedoch habe ich vorhin erst gelesen, dass die Portabilität 
von C auf Mikrocontrollern eine Illusion ist:
Beitrag "Re: Code von Atmel Mega8 auf ATtiny13"
Und der Mann, der das schrieb, hat wirklich Ahnung...

>
> Gruß,
>
> Frank

;-)

von Sven (Gast)


Lesenswert?

So ein ähnliches Problem hatte ich letztens auch.

Schau mal hier:

Beitrag "Wie sinnvoll ist ein union bei 32Bit Arm CPUs?"

von (prx) A. K. (prx)


Lesenswert?

Kluchscheißender Kluchscheißer schrieb:

> Das mag sein, jedoch habe ich vorhin erst gelesen, dass die Portabilität
> von C auf Mikrocontrollern eine Illusion ist:

Das ist keine Entschuldigung für miserablen Code.

Nicht, wenn man mehr macht als ein paar LEDs aus- und einzuschalten. Ich 
habe mir ein paar I/O-Module für UART, CAN, I2C, ... gebaut, die zwar 
auf AVR, LPC2000, STM32 alle verschieden implementiert sind, aber deren 
Interface nach oben weitgehend gleich ist. Darauf aufbauender Code ist 
folglich nicht mehr vom Controller abhängig und Portabilität wird ein 
Thema.

Und erst recht nicht, wenn man mit Kommunikationsprotokollen arbeitet. 
Wenn man damit nicht nur Selbstgespräche führt, dann ist irgendwann eine 
Node dabei, deren Byteorder nicht zu den übrigen Nodes passt.

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.