vier 8bit Variablen in eine 32bit Variable

Gast #3660625
Lesenswert?

Hallo,

ich möchte eine 32bit Zahl in ein CAN-Frame verpacken, vom RPi 
verschicken und in einem µC wieder entpacken.

Ist das so wie dargestellt richtig?
1
unsigned int _4567;
2

3
frame.data[4] = _4567;
4
frame.data[5] = _4567>>8;
5
frame.data[6] = _4567>>16;
6
frame.data[7] = _4567>>24;
7

8
[...]
9
sende ueber can 
10
[...]
11

12
uint32_t msg_in_32 = 0;
13

14
msg_in_32 = msg.data[7];
15
msg_in_32 = 8<<msg_in_32;
16
msg_in_32 = msg.data[6];
17
msg_in_32 = 8<<msg_in_32;
18
msg_in_32 = msg.data[5];
19
msg_in_32 = 8<<msg_in_32;
20
msg_in_32 = msg.data[4];
#3660633
Lesenswert?

test schrieb:

> msg_in_32 = msg.data[7];
> msg_in_32 = 8<<msg_in_32;
> msg_in_32 = msg.data[6];

Nope.
Hier überschreibst du dir ja msg_in_32 komplett!

Das ist nicht das was du willst. Denn selbst, wenn die vorhergehenden 
Operationen korrekt gewesen wären, wäre damit der 'Beitrag' von 
msg.data[7] komplett 'aus dem Rennen' genommen worden. Zuweisung ist 
Zuweisung. Und dabei wird der linke Teil von der Zuweisung unter 
Beachtung seines Datentyps komplett beschrieben.

Ausserdem stimmt die Angabe beim Verschieben nicht

    a << b

bedeutet: verschiebe den Inhalt von a um b Bits nach links.
Genauso wie

    a >> b

bedeutet: verschiebe den Inhalt von a um b Bits nach rechts.

Links von der Operation, egal ob << oder >>, steht das "womit". Und 
rechts von der Operation steht um "wieviele" Bits.
Liest du denn kein C Buch, ehe du mit programmieren anfängst? Da wirst 
du noch ein paar mal schön auf die Schnauze fallen.
#3660652
Lesenswert?

Hallo,

ich denke*, Du suchst etwas wie das Folgende, wobei msg_in_32 den 
übertragenen Wert enthält, der in die 4 Array-Werte msg.data[x] 
"aufgesplittet" wird.
1
msg.data[4] = (msg_in_32 & 0x000F);
2
msg.data[5] = (msg_in_32 & 0x00F0) >> 8;
3
msg.data[6] = (msg_in_32 & 0x0F00) >> 16;
4
msg.data[7] = (msg_in_32 & 0xF000) >> 24;

*Oder habe ich mal wieder einen kapitalen Denkfehler gemacht? ;-)
#3660655
Lesenswert?

Tobias S. schrieb:
> Hallo,
>
> ich denke*, Du suchst etwas wie das Folgende, wobei msg_in_32 den
> übertragenen Wert enthält, der in die 4 Array-Werte msg.data[x]
> "aufgesplittet" wird.
>
>
1
msg.data[4] = (msg_in_32 & 0x000F);
2
> msg.data[5] = (msg_in_32 & 0x00F0) >> 8;
3
> msg.data[6] = (msg_in_32 & 0x0F00) >> 16;
4
> msg.data[7] = (msg_in_32 & 0xF000) >> 24;
>
> *Oder habe ich mal wieder einen kapitalen Denkfehler gemacht? ;-)

Falsche Datenflussrichtung.
Er hat die 4 Einzelwerte und will sie zusammensetzen.
#3660660
Lesenswert?

Hallo Karl Heinz, ich zitiere mal von oben:
1
unsigned int _4567;
2

3
[...]
4
sende ueber can 
5
[...]
6
uint32_t msg_in_32 = 0;
7
msg_in_32 = msg.data[7];
8
[...]

für mich sah das so aus, dass er schon über CAN gesendet hat und den 
32bitter wieder auseinanderpfriemeln will, daher auch der Name 
msg_*in*_32.

Wie gesagt, wäre aber nicht das erste Mal, dass ich mich irre ;-)
Gast #3660677
Lesenswert?

TomA. schrieb:
> fasse deine Variablen, auf beiden Seiten, in einer "union" zusammen und
> das Problem ist gelöst.
Ja, aber nur wenn Ziel&Quell -Platform die selbe Endianness haben. 
Ansonsten sind die Bytes falsch herum. Wenn man hingegen Bitshifts wie 
oben verwendet, stellt der Compiler sicher dass sie immer die richtige 
Reihenfolge haben (LE in diesem Fall). So bleibt der Code portabel.
Moderator Persönliche Seite #3660761
Lesenswert?

Karl Heinz schrieb:
>>
1
msg.data[4] = (msg_in_32 & 0x000F);
2
>> msg.data[5] = (msg_in_32 & 0x00F0) >> 8;
3
>> msg.data[6] = (msg_in_32 & 0x0F00) >> 16;
4
>> msg.data[7] = (msg_in_32 & 0xF000) >> 24;
>>
>> *Oder habe ich mal wieder einen kapitalen Denkfehler gemacht? ;-)
>
> Falsche Datenflussrichtung.

Nicht nur das. Maskieren von Nibbles statt Bytes ist hier wenig 
zielführend. ;-)
Gast #3660881
Lesenswert?

msg.data[4] = (msg_in_32 & 0x000000FF);
 msg.data[5] = (msg_in_32 & 0x0000FF00) >> 8;
 msg.data[6] = (msg_in_32 & 0x00FF0000) >> 16;
 msg.data[7] = (msg_in_32 & 0xFF000000) >> 24;

oder erst schieben, und dann maskieren. ist dann immer 0xff:

..
 msg.data[4] = (msg_in_32 >>  0 ) & 0xff;
 msg.data[5] = (msg_in_32 >>  8 ) & 0xff;
 msg.data[6] = (msg_in_32 >> 16 ) & 0xff;
 msg.data[7] = (msg_in_32 >> 24 ) & 0xff;
..
Gast #3661044
Lesenswert?

hp-freund schrieb:
> Mit Zeigern kann man das Ganze doch einfacher machen oder?

Dann hast du aber genau das gleiche Problem wie mit unions:

Dr. Sommer schrieb:
> TomA. schrieb:
>> fasse deine Variablen, auf beiden Seiten, in einer "union" zusammen und
>> das Problem ist gelöst.
> Ja, aber nur wenn Ziel&Quell -Platform die selbe Endianness haben.
> Ansonsten sind die Bytes falsch herum. Wenn man hingegen Bitshifts wie
> oben verwendet, stellt der Compiler sicher dass sie immer die richtige
> Reihenfolge haben (LE in diesem Fall). So bleibt der Code portabel.

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