ich weis grad nicht, warum er das net macht: ich will eine 8Bit Zahl in eine 32Bit Zahl ganz nach links schieben. uint32_t temp=0; temp = ((0xa9)&0x000000FF)<<24 Aber im Debugger/Simulator ist nach dieser OP die Variable 'temp' immer (noch) Null.
Danke das geht. ISt aber komisch warum das andere nicht funzt. Es ist ein Code von einem anderen Compiler, der dort funkioniert.
im Weiteren will ich das folgende realisieren: Ich habe ein Array mit 4 Zellen (jedes 1 Byte) Nun sollen diese 4 Byte hintereinander in eine 32-Bit Variable. Ich muss aber mit Zeigern drauf zugreifen. So ist es bis jetzt:
1 | temp = *array++; + (*array++)<<8 + (*array++)<<16 + (*array)<<24; |
Da muss ein Fehler drin sein. Hab aber schon rumprobiert.
>temp = *array++; + (*array++)<<8 + (*array++)<<16 + (*array)<<24; >temp = *array++; Mach mal das Semikolon am Ende der Zeile weg ;)
ach das Semi nach dem ersten "array" .. sorry ist nur hier ein Schreibfehler. es geht sonst auch nicht.
Wenn ich es so mache, stimmen die Variablem tmp1..4. Aber beim Zusammenbau auf das 32-Ding bleibt dieses leer.
1 | tmp1=(*array++); |
2 | tmp2=(*array++); |
3 | tmp3=(*array++); |
4 | tmp4=(*array); |
5 | |
6 | temp = tmp1&0xFF + (tmp2&0xFF)<<8 + (tmp3&0xFF)<<16 + (tmp4&0xFF)<<24; |
Hi, auf jeden Fall ist da bei Dir ein Semikolon zu viel :) Falls das Byteordering stimmt, reicht ja vielleicht auch einfach ein Typecast für den Zeiger:
1 | temp = *(uint32_t*)array; |
Ansonsten eventuell so:
1 | temp = (uint32_t)array[0] + (uint32_t)array[1]<<8 + (uint32_t)array[2]<<16 + (uint32_t)array[3]<<24; |
CU
>temp = *array++; + (*array++)<<8 + (*array++)<<16 + (*array)<<24;
BIG_ENDIAN oder LITTLE_ENDIAN ?
Drehs mal um
temp = ((unsigned long)*array++)<<24 + ((unsigned long)*array++)<<16 +
((unsigned long)*array++)<<8 + *array;
Besser ?
Oder doch lieber
temp = *array++ + ((unsigned long)*array++)<<8 + ((unsigned
long)*array++)<<16 + ((unsigned long)*array)<<24;
da sProblem muss woanders liegen. selbst wenn ich keine Pointer benutze, nur Zahlen, assembliert der die nicht in die 'temp'
noch zwei Diagnosen: [c] tmp1=1; tmp2=2; temp = (tmp1<<8) + tmp2; {/c] Ergebnis: temp=0x00000102 [c] tmp1=1; tmp2=2; temp = (tmp1<<16) + tmp2; {/c] Ergebnis: 0x00000002 Warum mag er keine Shift über 16 Bit ??
Bevor sich hier alle den Mund fusselig reden: Achte auf deine Datentypen ! >tmp1=1; >tmp2=2; >temp = (tmp1<<16) + tmp2; Ist tmp1 ein unsigned long ?
hi holger, das Problem scheint was mit dem Shift zu sein. bis 15Bit schiebt er, danach ist immer Null. Also die komplette linke Hälfte der 32-Bit-Variable ist stets Null
alles klar, mit "long" gehts. Versteh ich aber nicht, warum das sein muss.
Du kannst eine 8 Bit Variable nicht um 16 Bits nach links schieben. Spätestens nach 8 Bits sind nur noch Nullen drin. Also immer erst typecast auf den BENÖTIGTEN Variablentyp bevor du schiebst.
Das Problem ist, dass er den 8Bit Typ shiftet, Und wenn man dann um mehr als 7 Bit shiftet, kommt eben automatisch 0 raus. Du brauchst erst einen Typecast auf eine 32Bit Variable. Danach kannst du shiften. Also tmp1 bis tmp4 als unsigned long definieren, wie schon gesagt wurde.
Noch eine Erkenntnis: Dies:
1 | temp = ((uint32_t)*array++) + (((uint32_t)*array++)<<8) + (((uint32_t)*array++)<<16) + (((uint32_t)*array)<<24); |
funktioniert nicht, da der Compiler die "++" wohl nicht hinternander ausführt, wie man denken mag, sondern einmal und dann 4 mal kopiert. Ich hatte damit immer das erste array-Byte viermal hinternander in "temp" Folglich bleibt nur o.g. Methode:
1 | temp = ((uint32_t)array[0]) + (((uint32_t)array[1])<<8) + (((uint32_t)array[2])<<16) + (((uint32_t)array[3])<<24); |
oder man schreibt die 4 Schritte untereinander als separate Befehle. :-)
> das Problem scheint was mit dem Shift zu sein. Das Problem ust vielmehr, dass du, Horst, dir endlich mal ein vernünftiges Buch über C reinziehen solltest, anstatt durch 'Try und Error' deine C-Kenntnisse zu erweitern. Beide Probleme, die du hier ansprichst sind nun wahrlich alte Hüte in C. > Dies: >
1 | > temp = ((uint32_t)*array++) + (((uint32_t)*array++)<<8) + (((uint32_t) *array++)<<16) + (((uint32_t)*array)<<24); |
2 | >
|
> funktioniert nicht, da der Compiler die "++" wohl nicht hinternander > ausführt, Dies funktioniert sehr wohl, aber nicht so wie du das erwartest. Der Punkt ist: Mit einer Anweisung wie der da, kann der Compiler machen was er will. Diese Anweisung hat auf jeden Fall undefiniertes Verhalten, und es wird vom C-Sprachstandard keinerlei bestimmtes Verhalten gefordert. Kurz gesagt: Eine Variable darf in einem Ausdruck nur einmal einen neuen Wert bekommen. Dein Ausdruck versucht aber in ein und demselben Ausdruck array 4-mal einen neuen Wert zuzuweisen -> undefiniertes Verhalten. Alles mögliche kann passieren. Und das arithmetische Berechnungen immer im Zahlenbereich int stattfinden (es sei denn einer der beteiligten Operanden hat einen höheren Datentyp), sollte sich auch schon rumgesprochen haben. Dabei ist es dem Compiler sche...egal, welchen Datentyp die Variable hat, dem das Ergebnis zugewiesen wird. Während der Berechnung des Ausdrucks gelten nur die Datentypen die innerhalb des Ausdrucks vorkommen. Erst nachdem das Ergebnis berechnet wurde, erfolgt die Anpassung auf die Zielvariable.
Horst wrote: > ISt aber komisch warum das andere nicht funzt. Es ist ein Code von einem > anderen Compiler, der dort funkioniert. Wenn es eine 32-bit-Umgebung ist: kein Problem. Beim AVR lebst du aber (C-mäßig) in einer 16-bit-Umgebung. Übrigens: egal, wie viele Nullen du vor die FF schreibst, die Zahl bleibt 16-bittig: 0xff, 255, 0x00ff und 0x000000ff sind alle dasselbe. Wenn sie 32-bittig werden soll, musst du entweder besagten typecast schreiben, oder den Suffix UL (groß oder klein geschrieben) dranhängen. C ist hier etwas trickreich: die Konstante 0xffffff würde automatisch als 32-bittig erkannt (da sie den Wertebereich des 16-bit-Integers überschreitet).
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.