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


von Norbert (Gast)


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!

von Andreas B. (Gast)


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-Tutorial#16-Bit_Portregister_.28ADC.2C_ICR1.2C_OCR1.2C_TCNT1.2C_UBRR.29

mfg Andreas

von A.K. (Gast)


Lesenswert?

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

von Wolfgang Horn (Gast)


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

von Norbert (Gast)


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.

von hans dieter (Gast)


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.

von Norbert (Gast)


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.

von hans dieter 2 (Gast)


Lesenswert?

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

von Peter D. (peda)


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

von Norbert (Gast)


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?

von Norbert (Gast)


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.

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
Noch kein Account? Hier anmelden.