LabVIEWForum.de
2er Kompliment 12bit fix-point integer - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+--- Thema: 2er Kompliment 12bit fix-point integer (/Thread-2er-Kompliment-12bit-fix-point-integer)



2er Kompliment 12bit fix-point integer - Slev1n - 23.11.2015 15:12

Hallo Leute,

bin mir nicht sicher, ob ich das hier nun im richtigen Teil des Forums poste aber habe eine ähnliche Frage unter "Allgemein" gefunden.

Ich lese über I2C 2 Bytes von einem Sensor aus die später die Temperatur bilden (AN4519 Seite 15). AN4519
Diese wird in I12.8 dargestellt. Also 12 Bits insgesamt und 8 davon stellen den Integer Teil da. Im Datenblatt steht, dass falls das erste Byte einen Wert größer 7F hat hat man eine negative Zahl und soll das "2s complement" anwenden (alle Bits negieren und +1). Mein Problem ist, dass ich am Ende von I16 nicht wieder zu meiner fixpoint Zahl komme.

Hab mal ein Snippet angehängt.

Hoffe ihr könnt mir helfen.

Gruß

Stefan

EDIT: Hab den Link hinzugefügt Smile


RE: 2er Kompliment 12bit fix-point integer - GerdW - 23.11.2015 15:53

Hallo Slevin,

probiere doch mal sowas hier aus:
[attachment=54694]
Wenn man etwas mit Integerdaten machen kann, sollte man nicht den Umweg über boolsche Arrays wählen…

Es wäre schön, wenn du deine AppNote verlinken könntest!


RE: 2er Kompliment 12bit fix-point integer - Lucki - 23.11.2015 18:59

Das geht aber viel viel einfacher. Ich erklärs mal ohne VI. Das 2er Komplement zur Vorzeichenfestleguung ist doch die normale Darstellung von Integer-Zahlen.
Das Problem ist hier nur, dass es nur die genormten Formate I16, I32, I64 gibt, nicht aber das Format I12. Das Vorzeichen ist im MSB enthalten.
Damit das Vorzeichen erkannt wird, ist folgende kleine Prozedur reforderlich:
1. Die 12-bit in I16 packen - eine andere Möglichkeit hast Du sowieso nicht.
2. Die Zahl 4bit nach links shiften, damit das Vorzeichen in das MSB kommt. Die Zahl ist dann schon vorzeichenrichtig, allerdings um den Faktor 2^4 = 16 zu groß.
3. Jetzt die Zahl - nein, nicht wieder nach rechts shiften, sondern: durch 16 dividieren.

[attachment=54703]

(natürlich kann man hier in einem Rutsch durch 256 dividieren. Die 2fache Division geschah hier nur aus didaktischen Gründen)

Edit: Habe in der Dok jetzt das gelesen:
[attachment=54704]
Die 12 bit der Tempratur sind also in den 2 Bytes bereits linksbündig angeordnet. Damit wird alles noch mal einfacher, und zwar so:
[attachment=54705]

Übrigens: Was die richtige Schreibweise von Fachbegriffen angeht, so kann man Dir da kein Kompliment machen.


RE: 2er Kompliment 12bit fix-point integer - Slev1n - 24.11.2015 10:42

Erstmal vielen Dank für die Hilfe!

Zitat:Übrigens: Was die richtige Schreibweise von Fachbegriffen angeht, so kann man Dir da kein Kompliment machen.

Das ist echt peinlich Smile Da war ich wohl zu schnell.

Also ich fasse mal zusammen um zu sehen, ob ich es verstanden habe.

1, MSByte und LSByte füge ich mit der "join" funktion zusammen zu einem U16 Wert, der dann zu I16 umgewandelt wird, da es ja ein vorzeichenbehafteter Wert sein kann.

2, Das Vorzeichen ist nun im MSB, da wo es hingehört. Würde ich nun bitshiften würde ich quasi das Vorzeichen verschieben, was blödsinn ist und deshalb teile ich durch 256 was zur richtigen Skalierung führt und LabVIEW das Vorzeichenbit immernoch richtig erkennen lässt.

3, Falls das MSByte > 0x7F ist (z.B. 0x80 = 1000 0000b) bekomme ich einen "sehr" negativen Wert. Aber macht das Sinn?
Anwendung des 2er Komplements: Alle Stellen invertieren und +1
0x80 = 1000 0000b ---> 0111 1111b + 0000 0001b = 1000 0000b --> maximal negativer Wert (Insofern LSByte = 0)
0x81 = 1000 0001b ---> 0111 1110b + 0000 0001b = 0111 1111b --> "weniger" negativer Wert

Mach also in meinen Augen Sinn, dass je größer die Zahl wird, nachdem das MSB von 0 auf 1 springt und somit ein '-' indiziert, der negative Wert geringer wird.

Berichtigt mich bitte falls ich falsch liege.

Gruß
Stefan


RE: 2er Kompliment 12bit fix-point integer - Lucki - 24.11.2015 10:59

(24.11.2015 10:42 )Slev1n schrieb:  3, Falls das MSByte > 0x7F ist (z.B. 0x80 = 1000 0000b) bekomme ich einen "sehr" negativen Wert. Aber macht das Sinn?
Anwendung des 2er Komplements: Alle Stellen invertieren und +1
0x80 = 1000 0000b ---> 0111 1111b + 0000 0001b = 1000 0000b --> maximal negativer Wert (Insofern LSByte = 0)
0x81 = 1000 0001b ---> 0111 1110b + 0000 0001b = 0111 1111b --> "weniger" negativer Wert
Das ist alles richtig

0111 1111 1111 1111 = 7FFF = 32767 (größte positive Zahl)
0000 0000 0000 0001 = 0001 = 1
0000 0000 0000 0000 = 0000 = 0
1111 1111 1111 1111 = FFFF =-1
1000 0000 0000 0000 = 8000 = -32768 (größte negative Zahl)

Ist doch ganz einfach: Wenn bei einem mechanischem oder elektronischem Rechenwerk 0000000 eingestellt ist und ich subtrahiere fortlaufend 1, dann fängt es wieder von ganz oben an und zählt dann rückwärts. Weil das so schön computergerecht ist, hat man es so genormt.

Für nicht genormte 12bit Integer gilt entsprechend:
0111 1111 1111 = 7FF = 2047 (größte positive Zahl)
0000 0000 0001 = 001 = 1
0000 0000 0000 = 000 = 0
1111 1111 1111 = FFF =-1
1000 0000 0000 = 800 =-2048 (größte negative Zahl)

Dein darstellbarer Temperaturbereich ist: -128.00°C .. +127.94°C. Die Temperaturdifferenz zwischen den Digits ist 1/16 °C. Von daher ist es sinnvoll, die Temperatur nur mit einer Nachkommastelle anzuzeigen und nicht, wie ich es gemacht habe, mit zwei.

Noch etwas:
Zitat:1, MSByte und LSByte füge ich mit der "join" funktion zusammen zu einem U16 Wert, der dann zu I16 umgewandelt wird, da es ja ein vorzeichenbehafteter Wert sein kann
.
Richtig, aber das ist nicht die einzige Möglichkeit. Wenn z.B. die beiden Bytes als Array vorliegen, dann kann man die 16bit Integer auch mittels Typumwandlung erzeugen.
[attachment=54712]