2 8bit in eine 16bit Zahl

OP #2294443
Lesenswert?

ja ,sorry das ist C.

Hab mich jetzt mal bissel bei sprut belesen.

Aber ich versteh noch nicht ganz wie ich die zwei byte jetzt quasi zu 
einem Word machen kann. wenn ich das eine byte beschreibe und danach das 
zweite dann hab ich doch das erste wieder überschrieben?

wäre es vielleicht so richtig
1
union _Word
2
    { 
3
    int Ergebnis;
4
    struct
5
         {
6
         char ECCPR1L;
7
         char ECCPR1H;
8
         };
9
    }Speicher;
Gast #2294445
Lesenswert?

union _Word
    {
    int Ergebnis;
    struct
         {
         char ECCPR1L;
         char ECCPR1H;
         };
    }Speicher;

int Test;
Speicher WordVariable;
char Var1;
char Var2;

WordVariable.ECCPRIL = Var1;
WordVariable.ECCPRIH = Var2;

Test = WordVariable.Ergebnis;
#2294449
Lesenswert?

Michael schrieb:
>  Außerdem kann Schieben je nach Prozessor recht ineffizient sein.

Stimmt, aber vermutlich wird kaum ein Compiler das als 8 left-shifts 
umsetzen


Christoph Herzog schrieb:
> wäre es vielleicht so richtig
>
>
1
> union _Word
2
>     { 
3
>     int Ergebnis;
4
>     struct
5
>          {
6
>          char ECCPR1L;
7
>          char ECCPR1H;
8
>          };
9
>     }Speicher;
10
>

Das kann funktionieren. Wenn der verwendete Prozessor ein Little-Endian 
ist. (Ist inzwischen fast von auszugehen, aber es wird im Originalpost 
nicht erwähnt)

Prinzipiell gefällt mir die ursprüngliche Variante am besten, es muss 
eben nur ein typecast rein:
1
Ergebnis = ((uint16_t) high << 8) | low
Gast #2294469
Lesenswert?

Warum muß das hier denn alles so kompliziert gelöst werden ??

Du definierst eine unsigned int-Variable namens Ergebnis und baust diese 
dann aus den beiden 8-Bit Werten wert1 (High-Byte) und wert2 (Low-Byte) 
zusammen:

unsigned int Ergebnis;

Ergebnis = wert1 * 256 + wert 2;    // Fertig !!

Das kann jeder C-Compiler der Welt verarbeiten.

Gute Compiler machen aus dem Teil ´* 256´ dann noch automatisch ein 
Links-Shift, weil das dann schneller geht als die echte Multiplikation, 
also

Ergebnis = (wert1 << 8) + wert2;

Womit wir dann wieder beim Anfang des Threads sind, der doch richtig war 
!!
Nur Ergbnis muß als unsigned int def. werden

Schieber
Gast #2294845
Lesenswert?

Alles beschrieben funktioniert natürlich nur mit vorzeichenlosen Werten.

Die union Konstruktion funktioniert nicht mit Hardware variablen, da in 
der struct ja nur neue Namen vergeben werden. Sind die schon belegt, 
meckert der Compiler. Schneller ist die union allemal.

Aber auch wenn der Compiler x*256 zu x<<8 optimiert, so wird er doch 
Probleme haben, das + zu optimieren. Je nach CPU ist | bedeutend 
schneller als +, wobei in diesem speziellen Fall beide Operationen zum 
gleichen Ergebnis führen.

Also lieber:

Ergebnis = (((uint16_t) high) << 8) | low;

Es ist ausserdem wichtig, dass "high" zuerst in eine 16 bit Zahle 
gewandelt wird, und dann erst nach links geshiftet wird. Daher nochmal 
zwei Klammern (auch wenn sie nicht unbedingt nötig wären).
Gast #2294884
Lesenswert?

Ähm Leute:
1
Ergebnis = ( ECCPR1H << 8 );
2
Ergebnis = Ergebnis + ECCPR1L;

Das H und das L impliziert doch, das ein HIGH und ein LOW Register ist.
Und da gehe ich davon aus, dass es auch ein 16bit-Pondon gibt:
1
Ergebnis = ECCPR1;

Der Compiler kümmert sich dann schon.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren