mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zweierkomplemente zusammenführen


Autor: fliege (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
Wert = (uint32_t)Byte_1 << 24 |
       (uint32_t)Byte_2 << 16 |
       Byte_3 << 8            |
       Byte_4;

Autor: fliege (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: fliege (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beitrag "Re: Zweierkomplemente zusammenführen"

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kluchscheißernder Nixwisser (kluchscheisser)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kluchscheißernder Nixwisser (kluchscheisser)
Datum:

Bewertung
0 lesenswert
nicht 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

;-)

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ein ähnliches Problem hatte ich letztens auch.

Schau mal hier:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.