Hallo,
ich habe ein 2 Dimensionales Array gsDataBuffer[][] aus 8bit Integer
Zahlen.
An einer Stelle, die zb. so aussieht:
...
0_ _0_ _0_ _0_ _1_ _1_ _1_ _1 ;
1_ _1_ _1_ _1_ _1_ _1_ _1_ _1 ;
...
möchte ich nun 12 Stellen (die mit den 1ern) zu einer 12bit langen Zahl
verknüpfen und in einer 16bit Variablen speichern.
Als Wert (value) sollte dieser herauskommen 2^12 -1 = 4095 (entspricht
12bit)
Dazu folgender Code:
Die 2. Dimension (column) ist hier konstant
###########################################
...
uint16_t value;
uint16_t data_low, data_high;
uint8_t position = numChannels - 1 - ((row*3)+color);
uint8_t posarray = position*3/2;
...
data_high = (((uint16_t)gsDataBuffer[posarray][column])&(15UL)); //liest
die ersten 4bit der "oberen" 8bit Zahl ein.
posarray++;
data_low = ((uint16_t) gsDataBuffer[posarray][column]); //liest alle
8bit der "unteren" 8bit Zahl ein.
value = (data_high<<8) + data_low; //Addieren
return(value);
###########################################
Leider erhalte ich als Ergebnis immer nur das "Low Byte" mit 0b11111111.
Wo kann hier der Fehler liegen?
Vielen Dank schonmal
In dieser Skizze, ist die Dimension "column" konstant,
es sind 2 "aufeinanderfolgende" 8bit Zahlen der Dimension "posarray" zu
sehen
...
0_ 0_ _0_ _0_ _1_ _1_ _1 _1 ; // 1
1_ 1_ _1_ _1_ _1_ _1_ _1 _1 ; // 2
...
Die niederwertigen 4Bit der 1. 8bit Zahl sollen die höchstwertigen der
12bit Zahl werden.
Die 8bit der 2. 8bit Zahl sollen die niederen 8bit der 12bit Zahl
werden.
Ausprobiert habe ich folgendes:
union { uint16_t u16;
uint8_t u8[2];} value;
value.u8[1] = (gsDataBuffer[posarray][column]&15);
posarray++;
value.u8[0] = gsDataBuffer[posarray][column];
return(value.u16);
Das Ergebnis bleibt leider immernoch das Selbe?
Vielen Dank euch schonmal für die Hilfe!
Tobi M. schrieb:> Die niederwertigen 4Bit der 1. 8bit Zahl sollen die höchstwertigen der> 12bit Zahl werden.> Die 8bit der 2. 8bit Zahl sollen die niederen 8bit der 12bit Zahl> werden.
Dann geht das mit der 'union' nicht, würde ich mal sagen. Da muss die
Byteorder stimmen (im Speicher sortiert von niedrigem zu hohem Byte).
Probiere mal:
1. ein kurzes Programm, wo nichts anderes gemacht wird, als 'Werte
umzuwandeln'. Kannste ja mal hier reinstellen. Ich glaube der Fehler
liegt wo anders.
Tobi M. schrieb:> uint8_t position = numChannels - 1 - ((row*3)+color);> uint8_t posarray = position*3/2;
... sieht mir nicht so gelungen aus: 'posarray' ergibt sich nicht aus
einer Berechnung ohne Rest. (Kann aber gewollt sein, der Rest ist dann
ein Offset, oder so)
2. wenn's geht: Die Anordnung der Daten ändern. Jede Zelle ist dann vom
Typ 'union xxx'.
Ralf schrieb:> Dann geht das mit der 'union' nicht, würde ich mal sagen. Da muss die> Byteorder stimmen (im Speicher sortiert von niedrigem zu hohem Byte).
Ganz im Gegenteil, mit Hilfe einer union kann man doch die
Speicherreihenfolge von HByte und LByte an die benötigte Byteorder
anpassen.
J.-u. G. schrieb:> Ralf schrieb:>> Dann geht das mit der 'union' nicht, würde ich mal sagen. Da muss die>> Byteorder stimmen (im Speicher sortiert von niedrigem zu hohem Byte).>> Ganz im Gegenteil, mit Hilfe einer union kann man doch die> Speicherreihenfolge von HByte und LByte an die benötigte Byteorder> anpassen.
Vielleicht meinen wir was Verschiedenes:
1
union
2
{
3
uint16_tW;
4
struct
5
{
6
uint8_tL,H;
7
}
8
}
Im Speicher stehen jetzt L und H hintereinander, was ja automatisch W
ergibt.
Ablauf:
Daten aus dem Array nach L und H übernehmen. W lesen. Das geht.
Ich hätte jetzt versucht die Originaldaten für die 'union' schon
zurechtzumachen (also Low- und High-Byte vertauschen), dann muss man nur
noch lesen.
Außer, ich habe mal wieder einen Denkfehler drin :-(
J.-u. G. schrieb:> Je nachdem ob DatenByte1 oder DatenByte2 das höherwertige ist, muss die> Zuordung zu value.u8[0] bzw. value.u8[1] erfolgen.
Genau. Dann kann man sich den Umweg über die Union allerdings sparen und
den 16Bit-Wert mit Shift und Or gleich zusammensetzen. Da allerdings
dort offensichtlich was nicht funktioniert, vermute ich, liegt der
Fehler in der Indizierung des Arrays.
Ralf schrieb:> Genau. Dann kann man sich den Umweg über die Union allerdings sparen und> den 16Bit-Wert mit Shift und Or gleich zusammensetzen
Ja, meistens gibt es mehrere Wege zum selben Ziel und jeder kann einen
für sich passenden aussuchen. Ich arbeite in Fällen wie hier lieber mit
der union, weil man meist ohne Operationen, sondern nur mit Zuweisungen
auskommt. Ich sehe darin auch keinen Umweg.
Ralf schrieb:> Da allerdings> dort offensichtlich was nicht funktioniert, vermute ich, liegt der> Fehler in der Indizierung des Arrays.
Das vermute ich auch.
Julian Schild schrieb:> for(i=0;i<=7;i++) {> result = result + (myValue[0][x]<<i);> x--;> }>> x=7;>> for(i=0;i<=7;i++) {> High = High + (myValue[1][x]<<i);> x--;> }>> result = result + (High<<8);> Zu kompliziert?
Der TO möchte sein Ergebnis aus 2 Werten des Arrays zusammenbasteln,
nicht aus 16. Die beiden Werte sind im Array so gespeichert, dass der
zweite Index (bei Dir x) für beide gleich ist.
Tobi M. schrieb:> Das Ergebnis bleibt leider immernoch das Selbe?
Hm, der Code sieht eigentlich OK aus. Aber vielleicht steht ja nicht das
richtige im Array ? Hast du mal data_high und data_low direkt ausgegeben
?
Das einzige was ich im original-Code seltsam fand ist die Konstante
"15UL", also unsigned long. Vermutlich ist long mindestens 32 bit, aber
es wird nur mit 16 bit Werten hantiert => ?
Ich wurde einfach 15U schreiben (obwohl der Compiler eventuell das ganze
durchschaut und den selben Code generiert ?)
ZigZeg
J.-u. G. schrieb:> Der TO möchte sein Ergebnis aus 2 Werten des Arrays zusammenbasteln,> nicht aus 16.
Verstehe ich das richtig. Er will einfach nur zwei 8 Bit Zahlen in einer
16 Bit Zahl vereinen? Lol. Wo ist das Problem?
1
uint8_tVar1=0,Var2=0;
2
uint16_tResult=0;
3
4
Result=Var1+(Var2<<8);
Voila. :P
Whs hab ich es schon wieder falsch verstanden^^.
Julian Schild schrieb:> Verstehe ich das richtig. Er will einfach nur zwei 8 Bit Zahlen in einer> 16 Bit Zahl vereinen?
So habe ich es auch verstanden.
Julian Schild schrieb:> uint8_t Var1 = 0, Var2 = 0;> uint16_t Result = 0;>> Result = Var1 + (Var2<<8);
Das wäre eine Möglichkeit und so hat es der TO auch versucht.
Julian Schild schrieb:> Wo ist das Problem?
Um das Problem einzugrenzen benötigen wir noch weitere Informationen des
TO. Es könnte an dem 2D-Array liegen, in dem die beiden 8-Bit-Zahlen
gespeichert sind.