Hallo liebes Forum, ich hänge an einer Stelle. Ich dacht es sei ganz einfach aber irgendwie bekomme ich es nicht hin. Ich möchte aus einer 8Bit Zahl eine 10Bit Zahl machen. Also aus 0xFF soll 0x3FF werden. Natürlich dachte ich einfach nur das ganze zweimal nach links schieben aber die "reingeschobenen" Zahlen sind Nullen. Also (0xFF << 2) ergibt 0x3FC. Die Bits 0 und 1 sind "0" Weiß von Euch jemand wie man das macht. Ich möchte natürlich nicht nur 0xFF convertieren. Es sollen alle Werte zwischen 0-255 sein. Hat jemand eine Idee? Grüße, Marcel
Das wird schwierig, weil informationen fehlen. Dein Beispiel: 0xFF kann jetzt 0x3FF, 0x3FE, 0x3FD, 0x3FC sein. Wie möchtest du entscheiden, was davon richtig ist? Der Ansatz mit dem Schieben ist schon ok so. Außer du hast mehrere Werte, dann kannst du interpolieren.
Entweder du hängst vorne oder hinten zwei Bits an, eine andere Möglichkeit hast du nicht. Hängst du sie vor die MSB, kannst du entweder Einsen oder Nullen anhängen. Einsen verschieben dir deinen Wert um 0x3FF, Nullen machen nichts. Verschiebst du deinen Wert um zwei Bit, musst du ja die zwei Bits erfinden. Egal wie du Bit 0 und Bit 1 wählst, die beiden sind geraten. Man kann keine höhere Auflösung durch Zauberei herstellen.
Marcel K. schrieb: > Hallo liebes Forum, > > ich hänge an einer Stelle. Ich dacht es sei ganz einfach aber irgendwie > bekomme ich es nicht hin. > > Ich möchte aus einer 8Bit Zahl eine 10Bit Zahl machen. > > Also aus 0xFF soll 0x3FF werden. Warum? Ich meine: Woran machst du fest, dass die unten 'reingeschobenen' Bits 1 sein sollen?
Hi >Also (0xFF << 2) ergibt 0x3FC. Die Bits 0 und 1 sind "0" >Weiß von Euch jemand wie man das macht. Es könnte also deiner Meinung nach 0c3FC, 0x3FD, 0x3FE oder 0x3FF sein. Wie entscheidest du, was davon richtig ist? MfG Spess
Ja, wenn ich jetzt genauer darüber nachdenke..... Ich hätte halt bei einem 8Bit 0xFF Wert, 0x3FF im 10 Bit PWM stehen. Es ist aber eigentlich egal. Ob jetzt 0x3FF oder 0x3FC im Timer steht. Danke für die schnelle Antworten und noch eine schöne Nacht, Marcel
Karl Heinz schrieb: >> >> Also aus 0xFF soll 0x3FF werden. > > Warum? > > Ich meine: Woran machst du fest, dass die unten > 'reingeschobenen' Bits 1 sein sollen? An den obersten beiden Bit der 8bit-Zahl?
Marcel K. schrieb: > Ja, wenn ich jetzt genauer darüber nachdenke..... > > > Ich hätte halt bei einem 8Bit 0xFF Wert, 0x3FF im 10 Bit PWM stehen. > > Es ist aber eigentlich egal. Ob jetzt 0x3FF oder 0x3FC im Timer steht. 0xFF != 0x3FF Wie kommst du auf diese Idee?
Na wenn ich mit einem 8Bit Wert 0x00 - 0xFF einen 10Bit PWM- Timer im "inverse-Mode" auch die 0x3FF erreichen kann. Wenn man jetzt 0xFF auf die 10Bit schiebt dann fehlt halt 0x03. Das ist aber OK für mich und hat sich geklärt. 0xFF = 100% "AN" bei 8 Bit, bei 10 Bit halt nur 99,7% "AN" Grüße
(variable << 2) | (variable & 0x01 ? 0x03 : 0x00) dupliziert das unterste Bit einfach somit bleibt 0 0 und FF wird zu 3FF
Hi, Marcel K. schrieb: > Ich möchte aus einer 8Bit Zahl eine 10Bit Zahl machen. > > Also aus 0xFF soll 0x3FF werden.
1 | uint8_t x8 = ...; |
2 | uint16_t x10 = x8 / 255.0 * 1023.0 |
Grüße, Markus
Marcel K. schrieb: > 0xFF = 100% "AN" bei 8 Bit, bei 10 Bit halt nur 99,7% "AN" 0xFF = 255 bei 8bit: 255/2^8-1 = 255/255 = 1 = 100% bei 10bit: 255/2^10-1 = 255/1023 = 0,249irgendwas = 25%
Markus schrieb: > uint8_t x8 = ...; > uint16_t x10 = x8 / 255.0 * 1023.0 Aber Floating Point muss man sich nicht aufhalsen. x10 = (int)(x8 * 1023L / 255); mfg.
:
Bearbeitet durch User
Marcel K. schrieb: > Na wenn ich mit einem 8Bit Wert 0x00 - 0xFF einen 10Bit PWM- > Timer im "inverse-Mode" auch die 0x3FF erreichen kann. Wenn > man jetzt 0xFF auf die 10Bit schiebt dann fehlt halt 0x03. Was genau gefällt Dir an der Idee nicht, die obersten beiden Bit in die untersten beiden einzukopieren? Das erfordert einen - allerhöchstens zwei - zusätzliche Assemblerbefehl(e).
Possetitjel schrieb: > Was genau gefällt Dir an der Idee nicht, die obersten > beiden Bit in die untersten beiden einzukopieren? Ja, das ist eine gute Frage, denn die Idee ist wirklich gut. Sie sorgt dafür, daß Minimum und Maximum des 8Bit-Zahlenbereichs auf Minimum und Maximum des 10Bit-Bereiches gemapped werden und verteilt gleichzeitig den dadurch entstehenden Abbildungsfehler so gleichmäßig wie möglich über den Gesamtbereich. Und das mit geringstem Rechenaufwand. Es ist wirklich nur ein einziger zusätzlicher Takt nötig. Es wäre geradezu sträflich dumm, NICHT diesen Weg zu verwenden.
c-hater schrieb: > und verteilt gleichzeitig den dadurch entstehenden Abbildungsfehler so > gleichmäßig Einziger Nachteil: sie macht einen großen Sprung in der Mitte. Bis dorthin wird immmer abgerundet, ab dort immmer "aufgerundet":
1 | 8 -> MSB|MSB -> 10 Bit -> Abstand zum Vorgänger |
2 | 0 00 0 |
3 | 1 00 4 4 |
4 | 2 00 8 4 |
5 | 3 00 12 4 |
6 | 4 00 16 4 |
7 | : |
8 | 126 11 504 4 |
9 | 127 11 508 4 |
10 | 128 11 515 7 --- ! |
11 | 129 11 219 4 |
12 | 129 11 223 4 |
13 | : |
14 | : |
Man könnte aber auch das vorletzte Bit als LSB mit einfließen lassen, dann werden aus einen einzigen Sprung drei besser verteilte Sprünge:
1 | 8 -> MSB -> 10 Bit -> Abstand |
2 | 0 00 0 |
3 | 1 00 4 4 |
4 | 2 00 8 4 |
5 | 3 00 12 4 |
6 | 4 00 16 4 |
7 | : |
8 | 62 00 248 4 |
9 | 63 00 252 4 |
10 | 64 01 257 5 -- |
11 | 65 01 261 4 |
12 | : |
13 | 126 01 505 4 |
14 | 127 01 509 4 |
15 | 128 10 514 5 -- |
16 | 129 10 218 4 |
17 | 130 10 222 4 |
18 | : |
19 | 190 10 762 4 |
20 | 191 10 766 4 |
21 | 192 11 771 5 -- |
22 | 193 11 775 4 |
23 | 194 11 779 4 |
24 | : |
Also mein Vorschlag:
1 | wert = wert<<2 + wert>>6; |
:
Bearbeitet durch Moderator
Lothar Miller schrieb: > Man könnte aber auch das vorletzte Bit als LSB mit > einfließen lassen, [...] Meine Güte. Ich zitiere: "Was genau gefällt Dir an der Idee nicht, die obersten beiden Bit in die untersten beiden einzukopieren?"
Wenn man aus einer 8-Bit-Zahl eine 10-Bit-Zahl machen will, dann multipliziert man sie mit 2x2 = 4 oder man schiebt sie einfach um 2 Bit nach links. Über die untersten beiden Bits kann keine Aussage gemacht werden. Man kann bei dieser simplen Transformation schließlich nicht mehr Informationen erfinden als da sind! Irgendwelche Informationen in den beiden LSB hinzuzuphantasieren ist einfach falsch und Unsinn. Also: Schieben um zwei Bits nach links und fertig. Die Auflösung bzw. der Informationsgehalt bleibt bei dieser Transformation dieselbe. Sie kann nicht besser bzw. gehaltvoller werden.
:
Bearbeitet durch Moderator
Frank M. schrieb: > Wenn man aus einer 8-Bit-Zahl eine 10-Bit-Zahl machen will, > dann multipliziert man sie mit 2x2 = 4 oder man schiebt sie > einfach um 2 Bit nach links. Das legst Du nicht fest. Wenn ich die 8bit-Zahl mit 4.011 multiplizieren will, dann tue ich das! Ehrlich! Es mag Dich auf das Äußerste empören - aber das ist nicht verboten!
Frank M. schrieb: > Die Auflösung bzw. > der Informationsgehalt bleibt bei dieser Transformation dieselbe. Sie > kann nicht besser bzw. gehaltvoller werden. Doch kann sie und das wurde oben auch schon gezeigt. Bei einer reinen linksschieberei handelt man sich automatisch einen offset ein, während beim behandeln der unteren beiden Bits die Skala von 10 bit besser ausgenutzt wird.
operator schrieb: > Doch kann sie und das wurde oben auch schon gezeigt. > Bei einer reinen linksschieberei handelt man sich automatisch einen > offset ein, während beim behandeln der unteren beiden Bits die Skala von > 10 bit besser ausgenutzt wird. Das klingt auf den ersten Blick zwar plausibel. Ich dachte auch zuerst, dass ich abwechselnd 01 und 10 in die beiden LSB schreiben würde, um einen besseren mittleren Wert zu bekommen. Aber auf den zweiten Blick empfand ich das als Irrtum, nämlich aus folgendem Grunde: Nehmen wir an, wir hätten einen 10-Bit-ADC. Wir lesen die Werte aus und können - aus welchen Gründen auch immer - sie nur als 8-Bit-Werte speichern. Wir werden dann bestimmt NICHT immer abrunden, wenn wir die Daten in 8 Bit quetschen wollen, also bestimmt KEINE Division durch 4. Wir werden das natürlich so machen: LSB 10->8 Bit =============== 00 abrunden 01 abrunden 10 aufrunden 11 aufrunden Das heisst: Die 8 Bit-Werte sind bereits teilweise aufgerundet! Wenn Du jetzt bei der Rücktransformation von 8 nach 10 Bit wieder irgendwelche LSB dazuaddierst, würde NOCHMALS auf die aufgerundeten Werte aufaddiert werden. Den von Dir angesprochenen Offset bekommst Du dann, wenn Du die LSB mit irgendwelchen Phantasien füllst. Die Werte sind dann nämlich systematisch zu hoch. Und genau das ist absoluter Unsinn. Deshalb darf nur mit 4 multipliziert bzw. um 2 Bits geschoben und KEINE LSB dazuerfunden werden. Alles andere ist falsch!
:
Bearbeitet durch Moderator
Wenn die 8 bit Werte z.B. von einem ADC kommen, könnte man auch immer 4 Messwerte addieren. Dann hat man auch im LSB etwas, Stichwort Oversampling...
StefG schrieb: > Wenn die 8 bit Werte z.B. von einem ADC kommen, könnte man auch immer 4 > Messwerte addieren. > Dann hat man auch im LSB etwas, Stichwort Oversampling... Du bekommst vom ADC bereits gerundete Werte. 50% davon sind bereits aufgerundet. Wenn Du da noch weitere LSB draufaddierst, hast Du falsche Zahlen.
Possetitjel schrieb: > Ich zitiere: "Was genau gefällt Dir an der Idee nicht, die obersten > beiden Bit in die untersten beiden einzukopieren?" Ach schlags kaputt, Leseschwäche... :-o
Das kommt wohl auf den konkreten Fall ab. Will ich einen Wertebereich ausnutzen, z.B. PWM von 0-100% dann ist reines Shiften eher unklug, da ich meine 100% dadurch nicht mehr erreiche. Will ich mit dem Wert weiterrechnen, z.B. eine Addition/Subtraktion mit einem hochauflösendem Wert (Festkommaarithmetik) dann ist es wohl Jacke wie Hose, was ich in den beiden Bits reinschreibe, denn sie sind eh erfunden. Dann kann ich genausogut einfach nur shiften.
Frank M. schrieb: > LSB 10->8 Bit > =============== > 00 abrunden > 01 abrunden > 10 aufrunden > 11 aufrunden Und auf was rundest du 1111111111 auf?
Die Aufgabenstellung definiert die Lösung. Wenn man den gesamten Bereich einer PWM abbilden will, dann sind Sprungstellen evtl. weniger wichtig als die Möglichkeit, an beiden Enden an den Anschlag gehen zu können. Wobei zu bedenken wäre, dass eine 10-Bit PWM eigentlich nicht 1024 sondern 1025 Stufen umfasst, wenn "ganz ein" und "ganz aus" mit von der Partie sind.
:
Bearbeitet durch User
Lothar Miller schrieb: > Possetitjel schrieb: >> Ich zitiere: "Was genau gefällt Dir an der Idee nicht, die >> obersten beiden Bit in die untersten beiden einzukopieren?" > Ach schlags kaputt, Leseschwäche... :-o Okay, akzeptiert.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.