Forum: Mikrocontroller und Digitale Elektronik Verliere Daten/Bits beim shiften in C/STM32


von Mike (Gast)


Lesenswert?

Hallo zusammen!

Ich habe ein sehr komisches Problem in einem C Programm auf einem STM32.

Ich lese einen Temperatursensor aus, dieser gibt mit ein 12 Bit Result 
zurück, diese wird in einer uint16_t gespeichert. Da die vier LSB 0 
sind, muss ich die 16 Bit Variable also um 4 bit nach rechts schieben 
bzw. durch 16 teilen.

Dabei gehen mir jedoch "in der Mitte zwischen den zwei Bytes" Daten 
verloren. Folgender Beispielcode liefert folgendes Ergebnis:
1
  HAL_UART_Transmit_IT(&huart2, &tempOut, sizeof(tempOut));
2
  tempOutRAW = tempOut / 16;
3
  HAL_Delay(1);
4
  HAL_UART_Transmit_IT(&huart2, &tempOutRAW, sizeof(tempOutRAW));

1
 OUTPUT:
2
0b0001 0110 1100 0000
3
0b0000 0001 0000 1100

Ich glaube der Fehler ist ziemlich Banal, aber irgendwie komm ich grad 
nicht drauf?!
1
tempOutRAW = tempOut >> 4;
 liefert das gleiche Ergebnis.



Viele Grüße,
Mike

von Mike (Gast)


Lesenswert?

Ergänzung:
Auch wenn ich mit weniger als 4 bit shifte (3 bit bzw. Division durch 8) 
verliere ich Daten "in der Mitte".

WTF?

von Alex D. (daum)


Lesenswert?

Das Problem liegt wahrscheinlich daran, dass die Daten als Little Endian 
gepseichert werden.

Bei Little Endian ist das niederwertigste Byte an der Stelle mit der 
kleinsten Adresse, wenn du dann den Wert einfach Byteweise ausgibts, 
wird zuerst das Low Byte, dann das High Byte ausgegeben.

Wenn man deine Ausgabe
1
0b0001 0110 1100 0000
2
0b0000 0001 0000 1100
Von Little-Endian zu einer "normalen" 16 bit Zahl ändert, kommt man auf
1
0b1100 0000 0001 0110
2
0b0000 1100 0000 0001
Der Shift funktioniert also anscheinend, aber dein Wert hat keine 4 0er 
am Ende, vielleicht vertauscht du beim lesen in einen 16 bit Wert die 
Bytes

von 900ss (900ss)


Lesenswert?

Alex D. schrieb:
> dass die Daten als Little Endian gepseichert werden

Das ist das Problem bzw. der UART-Transmit. Der überträgt die Bytes in 
der Reihenfolge, wie sie im Speicher liegen. Also LSB first.

von mh (Gast)


Lesenswert?

Mike schrieb:
> Folgender Beispielcode liefert folgendes Ergebnis:

Da fehlt so ungefähr alles was relevant ist, um die Frage beantworten zu 
können: die Datentypen!

von Peter D. (peda)


Lesenswert?

mh schrieb:
> Da fehlt so ungefähr alles was relevant ist

Insbesondere, wie in dem UART-Protokoll erkannt wird, welches das erste 
Byte eines Paketes ist.

von Cyblord -. (cyblord)


Lesenswert?

900ss D. schrieb:
> Alex D. schrieb:
>> dass die Daten als Little Endian gepseichert werden
>
> Das ist das Problem bzw. der UART-Transmit. Der überträgt die Bytes in
> der Reihenfolge, wie sie im Speicher liegen. Also LSB first.

Was überhaupt kein Problem darstellt und natürlich so gewollt ist. Der 
UART übeträgt dumpf einen Puffer. So muss das auch sein.

Am anderen Ende muss das Ergebnis nur wieder korrekt zusammengesetzt 
werden. Wäre da ein zweiter Controller am anderen Ende, der die Bytes 
einfach wieder in ein uint16 stopft, passt alles.
Will man die Daten anders empfangen muss man halt selbst mal 30 Sekunden 
nachdenken wie man aus den Bytes wieder einen uint16 Wert macht.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

mh schrieb:
> Da fehlt so ungefähr alles was relevant ist, um die Frage beantworten zu
> können:

Dafür, dass alles fehlt, wurde die Frage aber schon erstaunlich gut
beantwortet, und das gleich dreimal ;-)

> die Datentypen!

Mike schrieb:
> uint16_t

Wobei dasselbe Problem (wenn man hier überhaupt von einem Problem
sprechen kann) auch bei anderen Datentypen, wie bspw. uint32_t,
auftreten würde.

von 900ss (900ss)


Lesenswert?

Cyblord -. schrieb:
> Was überhaupt kein Problem darstellt

Deshalb funktioniert es bei dem TO auch ;)

Cyblord -. schrieb:
> Wäre da ein zweiter Controller am anderen Ende, der die Bytes einfach
> wieder in ein uint16
So allgemein ausgedrückt ist es dummes Zeug. Einen big endian Controller 
am anderen Ende und schon klappt das nicht mehr.

von Cyblord -. (cyblord)


Lesenswert?

900ss D. schrieb:
> Cyblord -. schrieb:
>> Was überhaupt kein Problem darstellt
>
> Deshalb funktioniert es bei dem TO auch ;)

Was am TO liegt und nicht am UART.

von 900ss (900ss)


Lesenswert?

Cyblord -. schrieb:
> Was am TO liegt und nicht am UART.

Ach?

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.