mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMEGA: uint32_t* / Speicherstellen


Autor: Marcel Pokrandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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??

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marcel Pokrandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marcel Pokrandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach doch statt der Multiplipation einen shift:

meineZahl = byte[1]<<24 + byte[2]<<16 + byte[3]<<8 + byte[4];

Rick

Autor: Marcel Pokrandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Marcel Pokrandt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.