Forum: Mikrocontroller und Digitale Elektronik Zwei Bytes zusammenfassen


von Fridel (Gast)


Lesenswert?

Wie ist es möglich aus 2 Bytes ein Byte zu gewinnen, indem jedes zweite 
Bit ausgelassen wird. Als Controller habe ich den ATTiny2313.

Kennt jemand einen schnellen Algorithmus?

Byte 0          Byte 2
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0

Neues Byte
7 5 3 1 7 5 3 1

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

neues_byte = byte0&0x80 + ((byte0&0x20)<<2) + ((byte0&0x08)<<4) + ...

von Amateur (Gast)


Lesenswert?

Möglicherweise wäre ein Beispiel, mit zwei signifikant unterschiedlichen 
Bytes, nicht verkehrt.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

(byte0 & 0xcc) | (byte1 & 0x66)

von Klaus (Gast)


Lesenswert?

Wenn 256 Bytes Platz im Flash ist, kann man eine Tabelle verwenden:

neues_byte = (table[byte0] << 4) + table[byte2];

Das Schieben könnte man auch noch einsparen, wenn man nochmal 256 Bytes 
Flash spendiert.

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Uwe B. schrieb:
> (byte0 & 0xcc) | (byte1 & 0x66)

Das ist falsch, die Bits werden abwechselnd geschoben, oder hab ich da 
was übersehen?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

bst Byte2, 7
bld Byte0, 7
bst Byte2, 5
bld Byte0, 6
bst Byte2, 3
bld Byte0, 5
bst Byte2, 1
bld Byte0, 4
bst Byte1, 7
bld Byte0, 3
bst Byte1, 5
bld Byte0, 2
bst Byte1, 3
bld Byte0, 1
bst Byte1, 1
bld Byte0, 0

von Kirsch (Gast)


Lesenswert?

Fridel schrieb:
> Byte 0          Byte 2
> 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
>
> Neues Byte
> 7 5 3 1 7 5 3 1

Byte A
a7 a6 a5 a4 a3 a2 a1 a0

Byte B
b7 b6 b5 b4 b3 b2 b1 b0

Neues Byte
a7 a5 a4 a3 a1 b7 b5 b3 b1


Das geht nicht einfach, da must du jedes Bit manuell an die richtige 
Stelle schieben:

Wolfgang R. schrieb:
> neues_byte = byte0&0x80 + ((byte0&0x20)<<2) + ((byte0&0x08)<<4) + ...

von Karl M. (Gast)


Lesenswert?

Naja,

Neues Byte
a7 a5 a4 a3 a1 b7 b5 b3 b1

sind neu Bits...

von npn (Gast)


Lesenswert?

Karl M. schrieb:
> Naja,
>
> Neues Byte
> a7 a5 a4 a3 a1 b7 b5 b3 b1
>
> sind neu Bits...

lass a4 weg, dann passt es :-)

von Fridel (Gast)


Lesenswert?

@ Wolfgang

Das Prinzip funktioniert. Verschlingt allerdings 50 Bytes.
1
nb  = (b0 & 0x80)
2
   + ((b0 & 0x20) << 1)
3
   + ((b0 & 0x08) << 2)
4
   + ((b0 & 0x02) << 3)
5
   + ((b1 & 0x80) >> 4)
6
   + ((b1 & 0x20) >> 3)
7
   + ((b1 & 0x08) >> 2)
8
   + ((b1 & 0x02) >> 1);

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Der Lookup-Table verschlingt vermutlich mehr... ;-) Dafür ist er 
deutlich schneller.

von Fridel (Gast)


Lesenswert?

Wolfgang R. schrieb:
> Der Lookup-Table verschlingt vermutlich mehr... ;-) Dafür ist er
> deutlich schneller.

Man könnte ja noch auf Assembler umsteigen. Das obige Beispiel von Knut 
werde ich mir auch noch ausprobieren.

von Klaus (Gast)


Lesenswert?

die bst/bld-Lösung ist schön.  Da lohnt die Tabelle höchstens noch, 
wenn's wirklich auf jeden Takt ankommt.

von beric (Gast)


Lesenswert?

Keine Ahnung :-)
1
; result in R0, byte 1 in R1, byte 2 in R2
2
; destroys R1 and R2 ! 22 CLKs!
3
4
rol R1  ; bit to carry
5
rol R0  ; carry to result
6
7
rol R1  ; skip one bit
8
rol R1  ; bit to carry
9
rol R0  ; carry to result
10
11
rol R1  ; skip one bit
12
rol R1  ; bit to carry
13
rol R0  ; carry to result
14
15
rol R1  ; skip one bit
16
rol R1  ; bit to carry
17
rol R0  ; carry to result
18
19
rol R2  ; bit to carry
20
rol R0  ; carry to result
21
22
rol R2  ; skip one bit
23
rol R2  ; bit to carry
24
rol R0  , carry to result
25
26
rol R2  ; skip one bit
27
rol R2  ; bit to carry
28
rol R0  ; carry to result
29
30
rol R2  ; skip one bit
31
rol R2  ; bit to carry
32
rol R0  ; carry to result

von c-hater (Gast)


Lesenswert?

beric schrieb:

> Keine Ahnung :-)

Stimmt, hast du nicht.

> 22 CLKs!

Und was soll daran besser sein als die 16 Ticks der bld/bst-Lösung?

von C-Beginner (Gast)


Lesenswert?

Hallo,

ernsthafte Frage (ganz ohne Ironie):

Fridel, wofür soll das gut sein? Was kommt da heraus ausser das ein Byte 
verschwindet - steckt da irgendeine clevere Logik dahinter?

mfg
C-Beginner

von Yalu X. (yalu) (Moderator)


Lesenswert?

In C (mit AVR-Builtin __builtin_avr_insert_bits):

1
#include <stdint.h>
2
3
uint8_t oddbits(uint8_t byte0, uint8_t byte2) {
4
  byte0 = __builtin_avr_insert_bits (0x7531ffff, byte0, byte0);
5
  byte0 = __builtin_avr_insert_bits (0xffff7531, byte2, byte0);
6
  return byte0;
7
}


Das ergibt:

1
oddbits:
2
  mov r0,r24
3
  bst r0,1
4
  bld r24,4
5
  bst r0,3
6
  bld r24,5
7
  bst r0,5
8
  bld r24,6
9
  bst r22,1
10
  bld r24,0
11
  bst r22,3
12
  bld r24,1
13
  bst r22,5
14
  bld r24,2
15
  bst r22,7
16
  bld r24,3
17
  ret

von c-hater (Gast)


Lesenswert?

Yalu X. schrieb:

> In C (mit AVR-Builtin __builtin_avr_insert_bits):
[...]

D.h.: Mit der doch recht speziellen Kenntnis einer einzigartigen 
Besonderheit des AVR-GCC kann man in C immerhin (nicht ganz) die 
Performance erreichen, die in Assembler möglich ist, wenn man einfach 
nur die rund hundert simplen Instruktionen des AVR kennt und beherrscht 
(statt der hunderte Seiten füllenden Details von C an sich und der 
weitere hunderte Seiten füllenden Beschreibungen eines speziellen 
Compilers bezogen auf ein spezielles Target-System)?

Außerdem: Sollten die angeblich doch so hocheffizent optimierenden 
C-Compiler nicht einfach alleine herausfinden können, wann der Einsatz 
der spezialisierten Macros sinnvoll wäre? Algorithmisch sehe ich da 
jedenfalls kein Problem. Es muß also wohl daran liegen, dass die 
Compiler doch nicht so gut sind, wie die C-Apologeten immer behaupten, 
dass sie es wären...

von Fridel (Gast)


Lesenswert?

> D.h.: Mit der doch recht speziellen Kenntnis einer einzigartigen
> Besonderheit des AVR-GCC kann man in C immerhin (nicht ganz) die
> Performance erreichen, ...

Deinem Beitrag entnehme ich, dass es in Assembler noch besser umzusetzen 
ist (kürzer?, schneller?). Kannst du ein Programm posten?

von S. Landolt (Gast)


Lesenswert?

Das von Knut Ballhause. Wenn man wie Yalu X. ein Quellbyte mit dem 
Zielbyte überschreibt, dann kann man Byte0 durch Byte2 ersetzen, die 
ersten beiden Zeilen weglassen, und ist bei 14 Takten.

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.