Hallo Leute,
ich habe mal wieder ein Problem. Diesesmal geht es um das 2er
Komplement. Ich möchte gerne, eine 2er Komplementzahl in eine
Dezimalzahl umwandeln aber ich weiß nicht wie ich das machen soll. Das
ganze soll im AVR-Studio geschehen und ein µC soll es mir nachher auf
dem Bildschirm ausgeben. Das 2er Komplement erhalte ich von einem
Beschleunigungssensor und ich würde diese Werte halt gerne Dezimal
ausgeben, so wie es unten kurz beschrieben ist:
Dez Bin Hex
+511 01 1111 1111 0x1FF
+510 01 1111 1110 0x1FE
...
+1 00 0000 0001 0x001
0 00 0000 0000 0x000
-1 11 1111 1111 0x3FF
...
-511 10 0000 0001 0x201
-512 10 0000 0000 0x200
Könnte mir jemand einen Tip geben, wie ich das im GCC realisiere oder
mir sogar einen kleinen Beispielcode dazu geben? Ich komme einfach
nicht weiter.
Schonmal danke und Gruß,
Marian
Liess die 10 Bit? von deinem Sensor ein (in ein 16bit int), teste ob das
10te gesetzt ist (=> negative Zahl) und setze dann bits 11-15 auf eins.
dann hast du einen 16bit int, der vorzeichenrichtig deinen Sensorwert
enthält.
/Ernst
Erstmal Danke an alle!
@Jörg: Leider funktioniert dein Vorschlag mit itoa nicht. Ich bekommen
immernoch Werte von 0 bis 1023 aber leider nicht die negativen die ich
haben möchte (also von -512 bis 511).
Hat noch jemand ne andere Idee oder muss ich an deinem Vorschlag nur
noch etwas ändern, denn was die 10 in itoa bedeutet weiß ich noch
nicht.
Leider kann ich sprintf nicht nutzen, weil ich wenig Ressourcen habe
und diese Funktion auch noch nicht ganz verstanden habe.
Gruß,
Marian
Du musst auf jeden Fall die Vorzeichenbits wie ich geschrieben habe
erweitern, sonst kann itoa, sprintf etc. garnicht wissen, dass es eine
negative zahl ist.
also
Der dritte Parameter im Aufruf von itoa ist die Basis für die
ausgegebene Zahl (also 10 -> dezimal). Wenn man eine 16 eingibt, ist
die Ausgabe hexadezimal usw...
@peter:
das stimmt so nicht:
der chip sendet -512, als bits:
0000 0010 0000 0000
nach deiner umrechnung kommt da 0 raus, nicht -512...
Beim kopieren eines 2er-Komplement werts in eine variable mit mehr
bits, muss man immer das Vorzeichenbit auf die neu hinzugekommenen Bits
kopieren, also:
1o bit eingelesen:
0000 0010 0000 0000
10er bit umkopiert in die "neuen" bits:
1111 1110 0000 0000
und voila, eine 16bit signed int variable, die den richtigen wert
enthält.
/Ernst
Nur mal so zur Info: Beide Varianten funktionieren! Die mit Y=X-1024 und
die mit dem einfügen der Einsen.
Danke nochmals an alle für eure Bemühungen.
Gruß,
Marian
@m@u:
das ist genau, was der compiler aus dem obigen code macht, die
einzelnen bitshifts+or-Verknüpfungen werden zur compilezeit aufgelöst,
und durch eine Konstante ersetzt.
Hat den Vorteil, dass man sich in einem Jahr nicht fragt, was die
magische "0xFC00" Konstante macht.
/Ernst
Eine eigene Frage?
Dieser Thread ist über 20 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.