Morgen Jungs und Mädels... Klasse Seite die ihr da habt. Hat mir schon oft weitergeholfen - jetzt hab ich aber ein kleines Problem. Es geht mir um folgendes. Ich lese von meinem IPod über den UART eine 4 Byte lange Zahl ein. Die berechne ich mir derzeit durch ne wilde Multiplikation in uint32_t und funktioniert aus super - is aber natürlich lahmarschig! Hab jetzt den Quellcode nicht da - sieht aber in etwa so aus: (uint32_t) meineZahl = (uint8_t)byte[3] + (uint8_t)byte[2] * 255 + (uint8_t)byte[3] * 16665[...] Ich dachte mir da - eigentlich sollte es doch möglich sein, direkt in die Datenstruktur uint32_t zu schreiben und mir dadurch die Berechnung zu sparen. Also hab ich mir nen Zeiger gebastelt und die 4 Bytes überprüft. Dummerweise hab ich nur die zwei niederwertigsten gefunden - kann also nur Zahlen bis ~~16000 darstellen. Die Bytes scheinen irgendwie nicht linear im Speicher angeordnet zu sein. In den Quellcodes der libc hab ich da nur ne typedef von uint32_t gefunden, die mir nicht weiterhilft. Weiss da einer was zu??
ja, das geht (ungefähr so, ist wohl nicht der schönste Code) uint32_t meineZahl uint8_t *meineZahlPointer = &meineZahl for (int i = 0; i<4; i++) { meineZahlPointer[i] = byte[i]; } Du legst also ein Feld über Deinen 32bit int. Ginge auch mit einer union: union { uint32_t zahl; uint32_t byte[4]; } meine; Allerdings bekommst Du u.U. dann ein Problem mit der endianess der Bytes, da der iPod möglicherweise big endian rechnet, der PC aber little endian.
Gerade so eine ähnliche Lösung hatte ich wie gesagt mit dem Zeiger schon ausprobiert. Und da wunderte ich mich darüber, dass er nur die 2 niederwertigsten Bytes ausgewertet hat. Aber ich muss zugeben: An eine Union-Struktur hatte ich noch gar nicht gedacht. Das hat bedeutend mehr Stil als mein Gefrickel mit dem Zeiger, Dereferenzierung etc. Ich werd das nochmal testen und werde berichten, obs geklappt hat.
PS. Mit dem Endian-Problem hast du übrigens Recht. Die Reihenfolge der Bytes mussten umgedreht werden. Das hatte ich aber schon berücksichtigt. Zumindest die Bitreihenfolge innerhalb der Bytes ist korrekt. Ist ja auch schonmal was wert.
Mach doch statt der Multiplipation einen shift: meineZahl = byte[1]<<24 + byte[2]<<16 + byte[3]<<8 + byte[4]; Rick
Das mit dem Shift funktioniert nur, wenn ich die einzelnen Bytes zunächst in ein uint32_t umwandel. Sonst hab ich nachher 4 Bytes mit dem Wert 0. Aber die Idee ist gut... g Wie gesagt. Ich werde heute abend oder die Tage mal das mit der Union-Struct versuchen
Oh mann oh mann... es war meine Blödheit. Die Berechnung war wohl von Anfang an OK - .da ich aber das Ergebnis mit der UTOA-Funktion ausgegeben habe und nicht wusste, dass die nur 16 Bit verarbeitet, hatte der das immer abgeschnitten. Für 32Bit Werte gibts die UTLOA.... Habs jetzt jedenfalls mit deinem Vorschlag übernommen und sieht jetzt so aus: uint32_t char4ToUint32(char* c) { union byteUint32union { uint32_t zahl; uint8_t byte[4]; } ; union byteUint32union unionzahl; unionzahl.byte[0] = c[3]; unionzahl.byte[1] = c[2]; unionzahl.byte[2] = c[1]; unionzahl.byte[3] = c[0]; return unionzahl.zahl; }
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.