mikrocontroller.net

Forum: Compiler & IDEs 16Bit Variable Wertigkeit umdrehen


Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe eine 16Bit Variable z.B.
mit dem Inhalt 0b1100000100000100 ich bräuchte aber die Wertigkeit 
gerade in die andere Richtung also 0b0010000010000011 gibt es da einen 
einfachen Weg das umzudrehen?

Ich hoffe ich habe mich einigermaßen Verständlich ausgedrückt.

Vielen Dank schonmal !

Autor: Blackbird (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So habe ich einen 12bit-Wert, der in einer 16bit-Variable gespeichert 
ist, umgedreht. Ist aber quick-and-dirty.

// 0b 0000 0001 0000 0100
// wird zu
// 0b 0000 0010 0000 1000
// die ersten 4 bits sind immer 0b0000
unsigned short ushort_rev(unsigned short x)
{
    unsigned short val = 0, mask;

  for(int i=0; i<12; ++i)
  {
    mask = x & 0x0FFF;
    mask = mask << (i+1);
    val &= ~(1<<i);
    val |= ((mask & 0x1000) >> 12-i);
  }
  return (val);
}

Blackbird

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  val = ( ((uint16_t)val) >> 8 ) | ( val << 8 );

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Buchegger:

einen swap meinte er nicht

Autor: pluto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Blackbird
Vielen Dank das war genau das was ich gesucht habe.

Würde mich Interessieren ob es noch eine andere Möglichkeit ohne 
Schleife gibt.

Autor: Martin Schneider (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann das auch über Tabellen machen,
entweder 1x 64kWorte oder aufteilen in 2 Bytes und eine 256Byte Tabelle

const u8 Tabelle[256] = { 0x00, 0x80, 0x40, 0xc0,
                          0x20, 0xa0, 0x60, 0xe0,
                          ....
                          0x3f, 0xbf, 0x7f, 0xff};

Val_u16 = ((Tabelle[Old_u16 && 0x00ff] << 8)
        +  (Tabelle[(Old_u16 >> 8) && 0x00ff]);


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin Schneider wrote:
> Man kann das auch über Tabellen machen,
> entweder 1x 64kWorte oder aufteilen in 2 Bytes und eine 256Byte Tabelle
>
> const u8 Tabelle[256] = { 0x00, 0x80, 0x40, 0xc0,
>                           0x20, 0xa0, 0x60, 0xe0,
>                           ....
>                           0x3f, 0xbf, 0x7f, 0xff};
>
> Val_u16 = ((Tabelle[Old_u16 && 0x00ff] << 8)
>         +  (Tabelle[(Old_u16 >> 8) && 0x00ff]);

Nibble-mässig ist wahrscheinlich eine gute Mischung
aus Laufzeit und Speicherverbrauch.

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int input;
int a;
int b = 0x0001;
int result = 0;

for(a = 0x8000;a>0;a/=2)
{
 if (input & a) result |= b;
 b *= 2;
}

oder nicht? Sollte so um die 16 Durchläufe brauchen...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
$ fortune -m '<<'
%% (fortunes)
   n = ((n >>  1) & 0x55555555) | ((n <<  1) & 0xaaaaaaaa);
   n = ((n >>  2) & 0x33333333) | ((n <<  2) & 0xcccccccc);
   n = ((n >>  4) & 0x0f0f0f0f) | ((n <<  4) & 0xf0f0f0f0);
   n = ((n >>  8) & 0x00ff00ff) | ((n <<  8) & 0xff00ff00);
   n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);

                -- C code which reverses the bits in a word.

Hatten wir schon mal.  Bei 8 bits lohnt sich das nicht, da ist die
einfache Schleife schneller und kleiner.  Bei 16 bits kann sich
das schon lohnen.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so geht das für 32 Bit. Einen Tack schneller gehts noch: bei 16 Bit 
kann man einmal die Bytes vertauschen und für nen Atmel Proz. kann man 
einmal 'swap' benutzen, das tauscht die 4Bit Hälften eines Bytes.

Cheers
Detlef

Autor: horst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie waere es mit

    val ^ 0b1111111111111111  ( eor 0xffff ) ?

gruss
       horst

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>val ^ 0b1111111111111111  ( eor 0xffff ) ?

da kommt das gleiche raus wie bei ~val...

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur zum Sammeln: Eine Möglichkeit habe ich auch noch. Allerdings als 
inline-assembler und damit nur auf AVR lauffähig:
#define swapbits(x) asm volatile (  "lsl %1\n\t ror %0 \n\t " \
"lsl %1\n\t ror %0 \n\t " \
"lsl %1\n\t ror %0 \n\t " \
[16 Mal]
"lsl %1\n\t ror %0 \n\t " \
"lsl %1\n\t ror %0 \n\t " \
: "=r" (x): "r" (x));

Das braucht exakt 32 Takte.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/***** Kehr die Reihenfolge der Bits um *****/
char turn8bit(char val)
{
  char i;
  char mirr;

  i = 0;
  mirr = 0;
  // Bits umtauschen
  while(i<8)
  {
    mirr |= ((val>>i)&0x1)<<(7-i);
    ++i;  
  }
  return mirr;
}

Das ist meine Lösung für PIC mit dem HT Compiler. Das lässt sich auch 
auf 16 Bit erweitern. Der Vorteil hier, es gibt nur zwei 
Shiftoperationen.

Viel Spaß dabei

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:

> Das lässt sich auch
> auf 16 Bit erweitern. Der Vorteil hier, es gibt nur zwei
> Shiftoperationen.

... pro Bit und beide Shifts haben eine variablen Shiftanzahl.

-> Assembler Code studieren. Wenn der µC keinen Shift mit einer 
variablen Anzahl an Stellen kann, artet das aus.

Abgesehen davon, ist es dieselbe Grundidee wie die hier
Beitrag "Re: 16Bit Variable Wertigkeit umdrehen"
nur eben langsamer

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.