Forum: Mikrocontroller und Digitale Elektronik reihenfolge der bits in einem byte umdrehen


von kernel_panic (Gast)


Lesenswert?

hallo alle!

ich möchte die reihenfolge der bits in einem byte mit C umdrehen. also
zb aus
10001001 -> 10010001 machen. muss ich das in einer schleife tun oder
gibt es dafür eine funktion.

von Stefan Salewski (Gast)


Lesenswert?


von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?


von k.m. (Gast)


Lesenswert?

das selbe problem mit dem bits-tauschen habe ich in bascom,die
genaue reihenfolge wie oben beschrieben brauche ich auch.wer kennt
sich mit bascom da aus.mit dem befehl shiftout komme ich hier nicht
weiter.eine 8 byte variable soll gedreht werden.
00001001 in 10010000
    ----    ----

oder eventuell, wie bekomme ich da noch vier bits dran ,sodas sich der
bcd-code nach links um 4 bits verschiebt.

von Michael U. (Gast)


Lesenswert?

Hallo,

abgesehen davon, daß ich mir nur schwer vorstellen kann, wie man zu 
einer inversen Bitfolge kommt (außer man lötet die I/Os z.B. am Display 
falsch rum an...):

in Assembebler als Schleife

ldi zaehler,8 ; Anzahl Bits

loop:
rol inreg ; oberstes Bit in C
ror outreg ; C oben reinschieben
dec zaehler
brne loop

Vielleicht als inline-asm einbinden?

Gruß aus Berlin
Michael


von Rahul D. (rahul)


Lesenswert?

>Vielleicht als inline-asm einbinden?
Eine Schleife könnte auch was bringen...

von Gelangweilter (Gast)


Lesenswert?

kann BASCOM nicht swappen? SHIFTOUT ist der falsche Weg. Der Befehl 
dient (jedefalls in FastAVR) zum schreiben von Schieberegistern an einem 
Pin. Die Nibbles eines Bytes vertauscht man da mit SWAP.

bye

Frank

von k.m. (Gast)


Angehängte Dateien:

Lesenswert?

hallo,und danke für die antworten. ja shiftout ist in der lage einmal
von links nach rechts und umgekehrt zuschreiben.je nachdem was man ihm
sagt,problem ist ich benutze eine fertige platine mit mc14015 und
mc14511.kann damit auch arbeiten,nur das prob ist die bits werden
in einer variable als bcd-code ausgegeben.shiftout taktet mir
normal 0000 1000 aus, das ergibt eine 8 auf dem led-display.
brauche aber 1000 0000 für die eins.wie erhöhe ich die 8 byte um 4 byte
nach links.mit swap habe ich bisher keinen erfolg gehabt oder ich
habe was falsch gemacht.hange mal mein bascom prog für eine uhr an,
komischer weise wenn ich in shiftout die bits deklariere mit -4 bit
kommt das heraus was ich brauche,zumindest bei scound eins .

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

> 0000 1000
> brauche aber 1000 0000

Swap macht genau das, es vertauscht die beiden Hälften eines Bytes. Im 
ersten Beitrag wolltest du das Byte aber komplett umdrehen. Was denn 
nun?

von Hannes L. (hannes)


Lesenswert?

Es ist ein großer Unterschied, ob man die Nibbles tauschen will (ASM: 
SWAP) oder die ganze Bitreihenfolge.

In ASM:

Nibbles tauschen: SWAP

Bitreihenfolge umkehren: Schleife mit LSL und ROR bzw. LSR und ROL

Bitfolge vertauschen: BST, BLD 8 mal hintereinander oder besser mittels 
Lookup-Tabelle und LPM über Pointer (schneller)

Ich glaube, es schadet auch dem Hochsprachenbenutzer nicht, sich mal den 
ASM-Befehlssatz des AVRs anzusehen. Der AVR kann nämlich keine 
Hochsprache.

...

von Rolf Magnus (Gast)


Lesenswert?

1
ldi zaehler,8 ; Anzahl Bits
2
3
loop:
4
rol inreg ; oberstes Bit in C
5
ror outreg ; C oben reinschieben
6
dec zaehler
7
brne loop

> Eine Schleife könnte auch was bringen...

Das ist doch eine Schleife. Um noch etwas Geschwnidigkeit rauszuholen, 
könnte man's auch auflösen und ohne Schleife machen:
1
rol inreg
2
ror outreg
3
rol inreg
4
ror outreg
5
rol inreg
6
ror outreg
7
rol inreg
8
ror outreg
9
rol inreg
10
ror outreg
11
rol inreg
12
ror outreg
13
rol inreg
14
ror outreg
15
rol inreg
16
ror outreg

Braucht grob dreimal soviel Flash wie die Schleife (32 bytes statt 10), 
ist dafür aber Faktor 2,5 schneller (16 statt 40 Taktzyklen) und spart 
ein Register.

von Dirk H. (arm-dran)


Lesenswert?

Rolf Magnus wrote:
>
1
> ldi zaehler,8 ; Anzahl Bits
2
> 
3
> loop:
4
> rol inreg ; oberstes Bit in C
5
> ror outreg ; C oben reinschieben
6
> dec zaehler
7
> brne loop
8
>
>
>> Eine Schleife könnte auch was bringen...
>
> Das ist doch eine Schleife. Um noch etwas Geschwnidigkeit rauszuholen,
> könnte man's auch auflösen und ohne Schleife machen:
>
>
1
> rol inreg
2
> ror outreg
3
> rol inreg
4
> ror outreg
5
> rol inreg
6
> ror outreg
7
> rol inreg
8
> ror outreg
9
> rol inreg
10
> ror outreg
11
> rol inreg
12
> ror outreg
13
> rol inreg
14
> ror outreg
15
> rol inreg
16
> ror outreg
17
>
>
> Braucht grob dreimal soviel Flash wie die Schleife (32 bytes statt 10),
> ist dafür aber Faktor 2,5 schneller (16 statt 40 Taktzyklen) und spart
> ein Register.


Man kann auch das weiter oben stehende Programm mit der schleife etwas 
optimieren ohne einen Zähler zu verwenden

             mov outreg,#1000000 binär
loop:
             rol inreg
             ror outreg

             bnc loop     (bnc = branch if carry not set)

fertig

setze das 8 Bit im Ausgangsregister
alle anderen löschen
nach 8 Schiebevorgängen wandert dieses Bit in Carry
Ende !!!!

von k.m. (Gast)


Lesenswert?

wie gesagt ich habe zwei möglichkeiten,mit shiftout.
wenn bcd-code 00001000 dann gebe ich eine 3 ein beim befehl und er
schreibt mir die folge von rechts nach links in den schieberegister.
bei einer 0 von links nach rechts,der mc14015 ist ein dual 4 bit 
register.
wenn ich dem shiftout sage schiebe nur 4 bits heraus macht er das.nur 
die reihenfolge ist immer seitenverkeht.von links schieben 0000 und 
rechts
1000. so die 1000 ergibt eine 8 - 0001 wäre die eins,darum wollt ich das
ganzen byte drehen. zur veranschaulichung 12345678 in 87654321,wenn das
so wäre,ist mein prob gelöst.
ich weiss wenn ich assembler könnte hätte ich es einfacher,nur möcht ich
mit dem hobby einfache sachen machen,denn helifliegen ist meine zweite
leidenschaft.

von Hannes L. (hannes)


Lesenswert?

> ich weiss wenn ich assembler könnte hätte ich es einfacher

Wenn ich mit Hochsprachen effizient umgehen könnte, hätte ich es oft 
auch einfacher... ;-)

Gibt es in den von Euch benutzten Hochsprachen denn keine Möglichkeit, 
ein Array mit Konstanten im Flash abzulegen und über Index darauf 
zuzugreifen? Das wäre zumindest in ASM die schnellste Methode.


...

von k.m. (Gast)


Lesenswert?

ja,hannes ,das gibt es bestimmt,prog mit bascom erst seit dezember 06.
werde mich wohl in bascom erstmal weiter vertiefen müssen,hät
nie gedacht das dieses prob mal so ausartet,werde wohl doch assembler
lernen und es einfacher habe.naja ein versuch war es wert.
jetzt wirds wieder wärmer und der heli will auch wieder raus.

danke für eure mühen

k.m.

von Dirk H. (arm-dran)


Lesenswert?

Hallo Hannes,

das wäre ja mit Kanonen nach Spatzen geschossen. Geschätze Routinengröße
270 Byte.
Was machst, wenn du 16Bit drehen möchstest.
Schau Dir mal meine Routine wieter oben an.

Noch kürzer gänge nur noch:

(Vorrausgesetzt der Prozessor hat nen Befehl zum direkte Bittausch)

Tausche Bit 8 mit 1
Tausche Bit 7 mit 2
Tausche Bit 6 mit 3
Tausche Bit 5 mit 4

Kürzer gänge es dann nicht mehr

von Hannes L. (hannes)


Lesenswert?

Ich weiß, ich mache das doch auch so. Habe ich doch weiter oben auch 
empfohlen. Jedoch nutze ich zum Rausschieben keinen Rotationabefehl, 
sondern nur den Shiftbefehl. Das gibt mir in einer Schleife (falls die 
Codegröße wichtig ist) die Möglichkeit, zuvor das Carry zu setzen, dann 
einmal das Quellregister zu rotieren, dann in der Schleife Zielregister 
zu rotieren und Quellregister zu schieben bis das Quellregister $80 
enthält (das zuerst einrotierte gesetzte Carry), das erspart den 
Bitzähler...

...

von Michael U. (Gast)


Lesenswert?

Hallo,

vielleicht sollte man nochmal die Aufgabenstellung klären???

"ich möchte die reihenfolge der bits in einem byte mit C umdrehen. also
zb aus"

damit ging es los.
Inzwischen weiß zumindest ich nicht mehr, was er eigentlich will...

@Dirk Hofmann:

             mov outreg,#1000000 binär
loop:
             rol inreg
             ror outreg

             bnc loop     (bnc = branch if carry not set)

fertig

Du schiebst eine 1 in outreg, bis die erste 1 in inreg auftaucht.
Was passiert mit den restlichen, wenn noch welche danach kommen?
Siehe Frage nach der Aufgabe...

Gruß aus Berlin
Michael

von Hannes L. (hannes)


Lesenswert?

> Du schiebst eine 1 in outreg, bis die erste 1 in inreg auftaucht.

Er schiebt nicht, er rotiert, fängt sich also den Carry-Müll wieder ins 
Quellregister ein und kann es dadurch nicht als Ende-Indikator nutzen.

;-)

...

von Dirk H. (arm-dran)


Lesenswert?

Lieber Michael,

noch mal im Klartext

Register OUTREG mit 80hex laden, also das oberste Bit ist gesetzt

Register INREG um eine Stelle nach Links verschieben,

Das 8. Bit ist jetzt in C

Register OUTREG um eine Stelle nach rechts verschieben,
wobei hier das Bit aus C an Stelle von BIT 7 wandert

Der obere vorher in OUTREG gesetzte Wert (Bit 7 gesetzt) wndert jetzt
nach Bit 6

usw.
nach 8 Schiebeoperationen kommt dieses bit ins Carry

und solange dieses nicht gesetzt ist wir d weitergeschoben.

Klar soweit ?

von Dirk H. (arm-dran)


Lesenswert?

Das ist keine 1 oben,

ist binäre Schreibweisse und bedeutet, das MSB ist gesetzt
hätte auch 80hex schreiben können

von Dirk H. (arm-dran)


Lesenswert?

Hannes,

was redest für nen Stuß?
Sorry

rotieren es sein den bei Euch ist es anders geht durchs Carry Flag, 
sonst für die obige Routine garnich gehen

von Hannes L. (hannes)


Lesenswert?

Ok, erledigt, sorum gehts auch...

...

von Michael U. (Gast)


Lesenswert?

Hallo,

Lieber Dirk,

ja doch, ja, doch, ich hätte eben besser lesen oder meine Brille 
aufsetzen sollen...

Witzigerweise kam ich anschließend genau auf diese Idee und da fiel es 
mir auf, aber hier wird ja in einem derartigen Tempo gepostet, wie soll 
man da klar denken können... ;-))))

Gruß aus Berlin
Michael

von Dirk H. (arm-dran)


Lesenswert?

Hallo Michael,

solltest Du wieder mal ne Lösung suchen,
kannst auch meine mail bekommen.
Helfe gern

Dirk

von k.m. (Gast)


Angehängte Dateien:

Lesenswert?

so,habe es geschafft,in bascom das problem meinerseits zu lösen.
wenn man die gedult nicht verliert,ist das kein problem,man muss
halt nur probieren was rauskommt.in bascom gibt es einen befehl
"shift x, left (oder right),bitanzahl" der dies ermöglicht.
er verschiebt die bits in der variable um die entsprechende anzahl
und ersetzt diese mit nullen,ob er auch andere bits reinschieben kann
muss ich erst noch testen,kann momentan dazu nichts sagen.
im anhang mein programm wie ich es haben wollte.

k.m.

von Hannes L. (hannes)


Lesenswert?

Tja, manchmal scheint es ja doch etwas zu bringen, die mitgelieferte 
Doku zu lesen...

;-)

...

von k.m. (Gast)


Lesenswert?

ja,gelesen habe ich sie nur in der demoversion ist da nicht viel 
dokumentiert.wie es mit der vollversion aussieht weiss ich nicht.
aber muss sagen das ich mit bascom zufrieden bin.werde mir aber
assembler doch mal anschauen und vllt werde ich mich durchringen
es zu lernen.

k.m.

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.