Forum: Mikrocontroller und Digitale Elektronik Wort invertieren und negativ darstellen


von *GAST* (Gast)


Lesenswert?

Hallo,
ich habe mnal wieder ein Problem und versuche die ganze Zeit schon eine 
Lösung zu finden.

0x025B sind 603
und
0xFFD6 sind -42


Diese beiden Referenzwerte habe ich aus einer SPS-Anlage ausgeschrieben. 
Die sind wirklich so!

Meine Funktion zum zusammenfügen der beiden Bytes sieht bis jetzt so 
aus:

zahl = bytes_verunden(d1, d2);

int bytes_verunden(int MSB, int LSB)
{
  int VALUE;
  VALUE = LSB << 8 | MSB;
  return VALUE;
}

Mit positiven Zahlen klappt alles super, sobald es negativ wird, kommen 
aber falsche Werte raus.

Ich muss also ab dem größtmöglichen Positiven Wert (dann ist die Zahl ja 
negativ) etwas anders machen. Aber was?

von STK500-Besitzer (Gast)


Lesenswert?

>Mit positiven Zahlen klappt alles super, sobald es negativ wird, kommen
>aber falsche Werte raus.

Es sind ja auch vorzeichenbehaftete Werte.
Übringens sind es keine Bytes...
Was willst du überhaupt mit den Werten machen? Was soll am Ende dabei 
herauskommen?

von blubber (Gast)


Lesenswert?

int bytes_verunden(int MSB, int LSB)
{
  int VALUE = (signed int)((LSB << 8) | MSB);
  return VALUE;
}

von Karl H. (kbuchegg)


Lesenswert?

Grundregel Nummer 1:

Wenn du auf Byte oder Wort-Ebene arbeitest, dann willst du alles 
mögliche haben, aber AUF KEINEN FALL EINEN C-DATENTYP MIT EINEM 
VORZEICHEN.

Um auf dieser Ebene zu arbeiten willst du weder
  char, signed char, int, signed int, long, signed long, double, float
benutzen.

Sondern du arbeitest ausschliesslich mit

   unsigned char
   unsigned int
   unsigned long

Alles andere kannst du vergessen, weil dir das bei allen signed 
Datentypen gebräuchliche Vorzeichen-Bit in der 2-er 
Komplementdarstellung, bei jeglichen Bitoperationen immer in die Quere 
kommt!

von blubber (Gast)


Lesenswert?

int16_t bytes_verunden(const uint8_t MSB, const uint8_t LSB)
{
  return (int16_t)(((uint16_t)LSB << 8) | MSB);
}

von Karl H. (kbuchegg)


Lesenswert?

blubber schrieb:
> int16_t bytes_verunden(const uint8_t MSB, const uint8_t LSB)
> {
>   return (int16_t)(((uint16_t)LSB << 8) | MSB);
> }


:-)
LSB und MSB vertauschen

von blubber (Gast)


Lesenswert?

Die Bezeichner und die Reihenfolge kommt nicht von mir. Die habe ich vom 
TE übernommen und da es bei unsigned vorher so klappte, stammt die 
falsche Bezeichnung vom TE. Von der reinen Operation ist es so bei ihm 
funktionsfähig, aber falsch benannt.

von Karl H. (kbuchegg)


Lesenswert?

blubber schrieb:
> Die Bezeichner und die Reihenfolge kommt nicht von mir. Die habe ich vom
> TE übernommen und da es bei unsigned vorher so klappte, stammt die
> falsche Bezeichnung vom TE. Von der reinen Operation ist es so bei ihm
> funktionsfähig, aber falsch benannt.

Wobei ich beim TE nicht davon ausgehen würde, dass er weiß was er tut 
:-)

von blubber (Gast)


Lesenswert?

Da sind wir uns einig... :)

von Peter D. (peda)


Lesenswert?

*GAST* schrieb:
> int bytes_verunden(int MSB, int LSB)
> {
>   int VALUE;
>   VALUE = LSB << 8 | MSB;
>   return VALUE;
> }

Die Funktion ist im Prinzip richtig, der Fehler passiert nämlich schon 
vorher.
Die Funktion will 2 int und nicht 2 char. D.h. beim Aufruf müssen Deine 
char erstmal nach int erweitert werden und da passiert das Unglück.
Aus einem 0x80 wird dann 0xFF80.

Schreib die Funktion um auf unsigned char Argumente und alles ist in 
Butter.

Generell sollte man für Variablen immer das kleinst nötige Format 
nehmen.


Peter

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.