Unter Verwendung eines 8-Bit-Flag-Registers besteht das Ziel darin, eine 16-Bit-Maske zum Manipulieren eines 2-Byte-Einstellungsregisters zu erzeugen, wobei benachbarte Bitpaare einen Kanal steuern, z. B. würde das Schreiben für Kanal 2 aus dem Flag-Register nehmen 0x2 (0b10)
und 0x04 (0b00000100)
erzeugen 0x0030 (0b0000000000110000)
mit einer konstanten Einstellungsmaske UND-verknüpft werden 0xAAAA (0b1010101010101010)
, was zu 0x0020 (0b0000000000100000)
.
Die äquivalente digitale Logik-"Schaltung" zum Erzeugen der Maske würde wie folgt aussehen:
Eine scheinbar einfache Möglichkeit, dies in Software zu implementieren, besteht darin, ein Bit für alle zwei Bits herauszuschieben (dh serieller Ansatz), wobei auf Endianness zu achten ist. In CPU12-Assembly (Big Endian):
LDX #2 ;counter: 2 bytes
L1 LDY #4 ;counter: 4 bits
LDAA flag ;get flag register
L2 LSRA ;shift lsb into carry
PSHC ;copy carry (ccr)
LSRB ;shift carry into msb
PULC ;paste carry
LSRB ;shift carry again
DBNE Y,L2 ;loops 4 times
PSHB ;store half-result (1 byte)
DBNE X,L1 ;loops 2 times
PULD ;retrieve resulting mask (2 bytes)
(1) Gibt es einen schnelleren Algorithmus für dieses Verfahren, ohne dass 24 MCU-Pins wie dargestellt verdrahtet werden müssen, oder eine Nachschlagetabelle; zB eine, die mehrere Bits gleichzeitig verarbeiten kann? (2) Gibt es einen Namen für dieses Verfahren?
Ich glaube, wonach Sie suchen, sind Morton-Zahlen von x
mit x
.
Verschiedene Möglichkeiten zur Berechnung von Morton-Zahlen: Bit Twiddling-Hacks
Spezialisierung der binären magischen Zahlenmethode für 8-Bit-Eingabe und 16-Bit-Ausgabe (Code im C-Stil):
uint16_t x; // set lower 8 bits of x for input
x = (x | (x << 4)) & 0x0f0f;
x = (x | (x << 2)) & 0x3333;
x = (x | (x << 1)) & 0x5555;
uint16_t res = x | (x << 1); // could also store result in place
Dies handhabt jede Kombination von Eingabebits. Bsp.: wenn x = 0x5
( 0b101
), dann res = 0x33
( 0b110011
)
Wladimir Cravero