Forum: Mikrocontroller und Digitale Elektronik Reihenfolge eines Bitfields umdrehen


von Martin Ulman (Gast)


Lesenswert?

Hallo Leute,
ich suche einen ASM-Befehl der auf meinem AVR die Reihenfolge eines
Bit-Felds umdreht. Es sollen also die Abfolge der Bits in einem Byte
herumgedreht werden. Aus
12345678 soll dann 87654321 werden, wobei die Ziffern die Position und
nicht den Wert angeben (der ist ja entweder 0 oder 1).

Gibt es sowas, oder wie löst man das am einfachsten?

Danke und Gruß
Martin

von A.K. (Gast)


Lesenswert?

LPM

von Martin Ulman (Gast)


Lesenswert?

Hy,
danke für den Tip, leider versteh ich nicht in wie fern der Befehl mir
hilft. Laut der Doku nimmt man den Befehl doch um aus dem
Programspeicher etwas mit einem Zeiger zu lesen, oder täusch ich mich
jetzt?

DAnke auf jeden Fall
Martin

von Uwe Nagel (Gast)


Lesenswert?

Ich schätze Du sollst in den Programmspeicher eine Tabelle
reinschreiben, die Du mit LPM ausliest. Das ist sicher die schnellste
Methode auf einem AVR. Ansonsten in einer Schleife rechtsrum
rausschieben und linksrum woanders reinschieben...
Einen eigenen Assemblerbefehl gibts nicht.

Uwe

von Ingo Henze (Gast)


Lesenswert?

Ich glaube es gibt keinen einzelnen Befehl dafür.

Meine Idee wäre ROL/ROR zu nehmen, und das ganz halt 8 mal.

Also mit ROL das höchste Bit ins C-Flag nach links raus schieben, dann
mit ROR wieder von rechts in ein zweites Register reinschieben und das
ganze 8 mal wiederholen.

Gruß
Ingo

von Martin Ulman (Gast)


Lesenswert?

Hey,
danke für die Antwort, ist natürlich schade das es nicht einfacher
geht, aber seh ich das richtig: wenn ich achtmal das erste bit
rausschiebe und das im einem extra register speichere, dann schieb ich
sie in umgekehrter reihenfolge wieder rein. Der Ansatz ist natürlich
recht aufwendig, aber wenn man es als proc schreibt, dann geht es noch.

Aber wie funktioniert das in Assembler? Leider ist mein Assembler nicht
so gut das ich mir das zutrauen würde. Wenn ich das richtig sehe dann
schiebt "LSL R1" ein Bit links raus und in das Carry-Bit. Dieses
müßte ich dann irgendwie speichern in einem zweiten Register, wie
funktionier das?

Danke auf jeden Fall
Martin

von Stefan Kleinwort (Gast)


Lesenswert?

Wichtig ist wohl, dass Du Dir darüber im klaren wirst, wie oft Du diese
Aktion machen musst, bzw. ob Du nach Laufzeit oder nach Codegröße
optimieren willst.

Hier wurde das schonmal ausführlich diskutiert:

http://www.mikrocontroller.net/forum/read-1-103946.html#103946

Viele Grüße, Stefan

von Martin Ulman (Gast)


Lesenswert?

Nachtrag:
Wäre folgende Möglichkeit nicht eine Lösung:
Ausgangssituation: in R1 ist das umzudrehende Byte drin, in R2 soll
nacher die Lösung rein.

Wenn ich jetzt acht-mal
LSL R1
ROR R2
mache, dann sollte es doch passen, oder nicht?

Danke für die Hilfe
Martin

von Martin Ulman (Gast)


Lesenswert?

Ich habs jetzt fürs erste mit einem Achtfachen Schieben hinbekommen, ist
leider sehr aufwendig, allerdings werde ich wohl beim nächsten mal
einfach meine Platine besser anpassen so das ich die bits nicht
umdrehen muß.

Danke auf jeden Fall

von thkais (Gast)


Lesenswert?

Wieso die Platine besser anpassen? Ich machs eher umgekehrt - ich route
meine Platine so, daß es am einfachsten wird (möglichst ohne Kreuzungen
und einseitig), und dann tausche ich die Portbits, wie ichs brauche.
Teilweise sind die Bits dann über drei Ports verteilt. Solange man
nichts wirklich zeitkritisches damit vor hat... Das bisschen Rechenzeit
hat man meistens noch übrig.

von Uwe Nagel (Gast)


Lesenswert?

Ich dachte auch, Du hast was mit FFT vor, da braucht man das sogenannte
Bit Reverse Shuffeling. Deshalb haben DSP's auch entsprechende Befehle
oder Adressierungsarten. Mit dem AVR geht's am schnellsten, wenn du
wirklich die Vertauschung vorausberechnest, in einer Tabelle ablegst
und mit LPM darauf zugreifst. Das ermöglicht auch absolut wilde
Vertauschungen von Bits, kostet aber 256 Byte für die Tabelle.

von Martin Ulman (Gast)


Lesenswert?

Nein, es ist lang nicht so kompliziert: Ich habe mir eine Platine
gebastelt und wollte mit dieser einen AVR mit einem LCD (2 Controller)
verbinden. Ich habe jedoch die Datenports falsch herum und dazu noch
nicht ab 0 sondern ab dem 2. Pin angelötet, deshalb mußten die
verschiebung leider sein. Aber in absehbarer Zeit werde ich wohl ganz
einfach die Datenpins richtig anlöten, dann spar ich mir den
Rechenaufwand, denn ich will möglichst viel fps auf das Display
bekommen, in der hinsicht spielt also Rechenzeit schon eine Rolle.

Nur rein Interessehalber: wie würde die sache mit einer Tabelle
funktionieren?

Danke
Martin

von kryon2000 (Gast)


Lesenswert?

vergiss es mit den Tabellen, Ein LPM BEfehl dauert 3 Taktzyclen und dann
noch viel Speicher im Flash. Desweiteren musst du noch ZH, ZL dafür
reservieren und und und.....

etweder so

rol r17
ror r16
rol r17
ror r16
rol r17
ror r16
rol r17
ror r16
rol r17
ror r16
rol r17
ror r16
rol r17
ror r16
rol r17
ror r16

oder

ldi r18, 8
s1:
rol r17
ror r16
dec r18
brne s1

von Peter D. (peda)


Lesenswert?

Martin,

"denn ich will möglichst viel fps auf das Display
bekommen, in der hinsicht spielt also Rechenzeit schon eine Rolle."


16 mal schieben dauert bei 16MHz 1µs, die Wartezeit pro Zeichen beträgt
aber etwa 40µs.

Das Umdrehen kostet Dich also keine nennenswerte Rechenzeit.


Peter

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.