mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zugriff auf einzelne Bytes z.B. bei UINT32


Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe folgendes Problem:
Ich programmiere gerade einen MSP430 in C (IAR Compiler).
Nun habe ich eine UINT32 Variable. Die wird ja intern in zwei Registern
abgespeichert, weil der Mikrokontroller ja so nur 16bit Variablen
speichern kann. Wie könnte ich jetzt direkt auf z.B. die obere hälfte
der Variable zugreifen. Direkt bedeutet, ohne große Schiebeoperationen
oder Divisionen. Gibt es da einen Trick? Ich hoffe, ihr könnt mir
helfen!

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal so...
typedef union {
        uint32_t i32;
        struct {
                uint8_t i8l1;
                uint8_t i8l2;
                uint8_t i8h1;
                uint8_t i8h2;
        };
} convert32to8;

Aus dem AVR GCC Tutorial...
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

mfg Andreas

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was stört dich an der einzig universell nutzbaren shift-and-mask
Methode?

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, A.K.,

"Was stört dich an der einzig universell nutzbaren shift-and-mask
Methode?"
Eine Anweisung wie "TCCR1B = BV(WGM12) | BV(CS12);" ist wunderbar,
wenn einzelne Bits zu bearbeiten sind.

Aber wenn ein PLL-Baustein ein einziges Datenwort verlangt, das auch 3x
u12-Zahlen zusammengesetzt ist und 6 Flags, dann bilde ich das lieber in
einer Struktur ab und bette die in eine union ein, damit ich einerseits
leicht berechnen, schreiben, und auch leicht lesen kann.

Ciao
Wolfgang Horn

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch.

Ich benutze das bei einer Mittelwertberechnung. Anstatt 16mal nach
links zu shiften, kann ich jetzt einfach die beiden oberen Byte nehmen.
Das geht natürlich deutlich schneller.

Autor: hans dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und bei einem anderen packing oder gar anderen compiler funktioniert das
program nicht mehr!
es gibt übrigens für sicherheitsrelevante und automotive anwendung
gewisse regeln (siehe MISRA), die auch ihren grund haben. und eine
davon ist, dass man unions nicht verwenden soll.
aber solange du die software nur für dich schreibst ist mir das egal.

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum denn gleich so aggressiv???

Es gibt Momente, da sind die Fähigkeiten eines Programmes wichtiger als
seine Portabilität. Für eine Lösung mittels shiften hätte ich nicht
genug Zeit. So geht es deutlich schneller und es passt. Anstatt Unions
zu verwenden, könnte ich natürlich auch inline assembler verwenden. Ich
glaube aber kaum, dass das größere Sicherheit bietet und portabler ist.

Autor: hans dieter 2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hans dieter  bitte verlaße dieses forum.ich will dich hier nicht
schreiben sehen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Norbert,

"Für eine Lösung mittels shiften hätte ich nicht genug Zeit. So geht
es deutlich schneller und es passt."


Ich kenne den MSP430 Compiler nicht, aber wenn dem wirklich so ist,
dann wäre er extrem grottenschlecht.

Alle Compiler, die ich kenne, werden hellhörig, wenn sie sowas wie
"<<8" oder "*256" sehen und optimieren das sehr gut. Da sind
schlechtestenfalls 1..2 Zyklen überflüssiger Code drin und das merkt
keine Sau.

Werf doch einfach mal nen Blick ins Assemblerlisting, ob der MSP430
Compiler wirklich so grottenschlecht optimiert.


Peter

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm...ich habs gerade mal ausprobiert. Es sind doch weniger Befehle als
ich dachte beim shiften. Die Union Lösung ist aber immer noch deutlich
kürzer. Aber zumindest theoretisch müssten jetzt beide Lösungen
passen.

    ConvertLongToShort  Threshold;
    unsigned long              Schaltschwelle;

// benötigt 5 Zyklen
    Threshold.UINT32 -= Threshold.UINT16H + TAR;

// benötigt 14 Zyklen
    Schaltschwelle -= (Schaltschwelle >>16) + TAR;


Klar ist die Union Lösung ein wenig, nennen wir es mal hingetrickst.
Aber ich denke, solange man weiß, was man da tut, ist das doch okay,
oder? Wie würdet ihr das sehen?

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht nochmal kurz zuim Hintergrund, warum ich hier so ein
"Aufstand" mache wegen ein paar Taktzyklen. Die Mittelwertberechnung
ist Teil einer AD-Wandlung. Zwischen den einzelnen Messungen habe ich
lediglich etwa 50 Taktzyklen Zeit.

Zurzeit bin ich zwar erst bei 22 Taktzyklen, es muss aber noch etwas
Platz bleiben, da später noch Zähler gesetzt werden müssen usw.

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.