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?
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; |
Warum ist bei Byte 1 und Byte 2 eine Variablendeklaration von uint32t vorgesetzt und bei Byte 3 & 4 nicht? Oder war das nicht Absicht?
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;
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.)
Beitrag "Re: Zweierkomplemente zusammenführen" "Zweierkomplemente" spielen dann keine Rolle. Du musst aber wissen, welchen Datentyp du letztendlich für wert brauchst.
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
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.
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
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 ;-)
So ein ähnliches Problem hatte ich letztens auch. Schau mal hier: Beitrag "Wie sinnvoll ist ein union bei 32Bit Arm CPUs?"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.