Forum: Mikrocontroller und Digitale Elektronik Bits effektiv umsortieren in C


von Luky (Gast)


Lesenswert?

Ich habe ein paar Eingänge an verschiedenen Ports des AVRs die aber 
leider "Layoutoptimiert" angeordnet wurden. Ich muss also die Ports 
einlesen und die Bits umsortieren, sodass sie logisch verwertbar sind. 
Wie Kann man das in C am effektivsten erledigen?

von Peter II (Gast)


Lesenswert?

Luky schrieb:
> Wie Kann man das in C am effektivsten erledigen?

das schnellste ist

uint8_t portmap[256] = { .... };
uint8_t out_data = portmap[ in_data ];

braucht aber halt 256byte ram.

von slow (Gast)


Lesenswert?

Verwerte die Bits doch einzeln.

von Luky (Gast)


Lesenswert?

wie soll ich die Bits einzeln verwerten? Beim einlesen jedes Bit des 
Ports einzeln maskieren und an die richtige Stelle schieben? 
Funktioniert zwar wunderbar, klingt aber nicht effizient...

von Peter D. (peda)


Lesenswert?

Schau mal hier:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296

Da werden 4 Bits eines Bytes auf 4 verschiedene Leitungen ausgegeben.
Das läßt sich leicht auch für Eingänge umschreiben.

Testen und Setzen ist effektiver als Schieben.


Peter

von Uwe (Gast)


Lesenswert?

Bau dir ne Routine in Assembler z.B. so :

SBIC pina,0
SBR  r16,0x80
SBIC pina,1
SBR  r16,0x40
SBIC pina,2
SBR  r16,0x20
SBIC pina,3
SBR  r16,0x10
SBIC pina,4
SBR  r16,0x08
SBIC pina,5
SBR  r16,0x04
SBIC pina,6
SBR  r16,0x02
SBIC pina,7
SBR  r16,0x01

von Optimierer (Gast)


Lesenswert?

Luky schrieb:
> klingt aber nicht effizient...

Was ist effizient? Wie zeitkritisch ist es? Oft genug wird an Stellen 
rumgemurkst um sie 'effizient' zu machen obwohl direkt danach der µC 
sich für 5000 Takte schlafen legt.
Dafür wird der Code dann schier unlesbar.
Also erst prüfen ob der Aufwand wirklich notwendig ist.

von Peter II (Gast)


Lesenswert?

Optimierer schrieb:
> Dafür wird der Code dann schier unlesbar.

was ist an eine Tabelle nicht lesbar?

von Detlev T. (detlevt)


Lesenswert?

Peter II schrieb:
> braucht aber halt 256byte ram.

Man kann eine solche Tabelle ja auch ins Flash packen.

von Peter D. (peda)


Lesenswert?

Uwe schrieb:
> Bau dir ne Routine in Assembler z.B. so :

Nö.

Assembler nimmt man unter C nur, wenn es dafür auch einen triftigen 
Grund gibt.
Und der fehlt hier völlig. Die C-Syntax bietet genug Möglichkeiten.


Peter

von Optimierer (Gast)


Lesenswert?

Peter II schrieb:
> was ist an eine Tabelle nicht lesbar?

Nix, das habe ich ja nicht gemeint. Ich meinte allgemein Optimierungen, 
die oft genug dann  schlechter lesbar sind (z.B. Funktionen in 
Assembler) obwohl sie eine Optimierung an der Stelle gar nicht notwendig 
ist.
Z. B. Der Vorschlag Tabelle in Flash packen. Wie schnell ist ein Flash 
Zugriff? Ist das dann wirklich schneller als Testen und Setzen wie von 
Peter Danegger vorgeschlagen?
Ich habe mich nur an dem Begriff

Luky schrieb:
> klingt aber nicht effizient...

aufgehängt, weil oft genug sinnlos versucht wird zu optimieren und raus 
kommt dann ein schlecht wartbarer oder gar fehlerhafter Code.

von Michael D. (etzen_michi)


Lesenswert?

Ich mache das gerne so das ich (wenn möglich) zumindest ein paar in der 
Richtigen reihenfolge habe und dann z.B.

PORTB= (PORTB&0xF0)+(Daten&0x0F);

oder wenn geschoben werden muss:

PORTB= (PORTB&0xE1)+((Daten&0x0F)<<1);

Wie effizient das genau ist habe ich noch nie ausgerechnet/drüber nach 
gedacht.

von Luky (Gast)


Lesenswert?

Also kurz zusammengefasst: ich habe eine 8Bit eingangsvariable 
u8_PortIn. Die 8Bits dort müssen aber umsortiert werden in eine neue 
Variable
u8_InSort. Wie geht das also am effizientesten? DieOperation wird 
ständig ausgeführt, ist also tatsächlich zeitkritisch.

von Peter II (Gast)


Lesenswert?

Luky schrieb:
> Wie geht das also am effizientesten?

steht schon oben, per tabelle. Schneller geht es nicht.

von Karl H. (kbuchegg)


Lesenswert?

Luky schrieb:
> Also kurz zusammengefasst: ich habe eine 8Bit eingangsvariable
> u8_PortIn. Die 8Bits dort müssen aber umsortiert werden in eine neue
> Variable
> u8_InSort. Wie geht das also am effizientesten?

Das hängt auch davon ab, wie die genaue Aufteilung ist.
Sind sie komplett durcheinander, dann wird wohl Einzelbfrage + 
Neuzusammenbeu eines Bytes die schnellere Lösung sein. Sind sie aber 
schon fast in der richtigen Reihenfolge, dann könnte ein oder 2 mal 
schieben besser sein.

> DieOperation wird
> ständig ausgeführt, ist also tatsächlich zeitkritisch.

Das heist noch lange nichts.
Zeitkritisch ist eine Sache dann, wenn es eine extern erzwunge 
Zeitvorgabe gibt, die eingehalten werden muss. Wir sind ja nicht beim 
Bund, bei dem das Entleeren eines Papierkorbes zeitkritisch ist, nur 
weil der Spiess das genau jetzt haben will und man dann vor Langeweile 
bis zum Mittag erst mal eine Runde pennt.

von Peter II (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> dann wird wohl Einzelbfrage +
> Neuzusammenbeu eines Bytes die schnellere Lösung sein.

nein ganz bestimmt nicht.

von Karl H. (kbuchegg)


Lesenswert?

Peter II schrieb:
> Karl Heinz Buchegger schrieb:
>> dann wird wohl Einzelbfrage +
>> Neuzusammenbeu eines Bytes die schnellere Lösung sein.
>
> nein ganz bestimmt nicht.

Ja, hast recht. An die Tabelle hab ich nicht mehr gedacht.

von Peter D. (peda)


Lesenswert?

Luky schrieb:
> DieOperation wird
> ständig ausgeführt, ist also tatsächlich zeitkritisch.

Ein Uhrenprogramm zählt auch ständig die Stunden hoch, aber niemand wird 
dazu zeitkritisch sagen.

Zeitkritisch ist eine Task, wenn sie 50% der CPU-Zeit benötigen muß.
Zeitlich zu berücksichtigen ist eine Task, wenn sie 5% der CPU-Zeit 
benötigen muß.
Alles andere ist erstmal unkritisch.


Peter

von Peter II (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Zeitkritisch ist eine Task, wenn sie 50% der CPU-Zeit benötigen muß.
> Zeitlich zu berücksichtigen ist eine Task, wenn sie 5% der CPU-Zeit
> benötigen muß.
> Alles andere ist erstmal unkritisch.

das ist blödsinn.

50% der CPU-Zeit in welchen Zeitraum? Wenn die berechnung läuft dann 
sind es 100%. Wenn ich ein timing einhalten muss und dafür die 
berechnung brauche dann ist es Zeitkritisch. Auch wenn diese vorgang nur 
1 mal in der stunde vorkommt.

von Luky (Gast)


Lesenswert?

Die Umwandlung IST zeitkritisch, da sie direkten Einfluss auf die 
maximal mögliche Abtastrate hat. Je schneller die Umwandlung, desto mehr 
Messungen können durchgeführt werden.
Und bevor hier wieder jemand mit "Anforderungen" etc kommt: So schnell 
wie mit einem AVR und 20MHz Takt möglich ist in meinem Fall eine 
ausreichende "Anforderung".
Das mit der tabelle wird aber leider etwas schwierig da ich 3 Ports 
einlese und den specicher nicht erübrigen kann. Leider.

von Peter II (Gast)


Lesenswert?

Luky schrieb:
> Das mit der tabelle wird aber leider etwas schwierig da ich 3 Ports
> einlese und den specicher nicht erübrigen kann. Leider.

kannst du tabelle ja in den Flash legen, das sollte wenn überhaupt nur 
minimal langsamer sein. Dort sind dann die 3x256 byte meist nicht das 
Problem.

von Karl H. (kbuchegg)


Lesenswert?

Luky schrieb:
> Die Umwandlung IST zeitkritisch, da sie direkten Einfluss auf die
> maximal mögliche Abtastrate hat. Je schneller die Umwandlung, desto mehr
> Messungen können durchgeführt werden.

Aha.
Und das wusste man vorher nicht, so dass man die Pins auf Biegen und 
Brechen im Layout so anordnet, dass die softwaremässige Behandlung beim 
Einlesen möglichst wenig Zyklen braucht.

Tja. Dumm gelaufen.
Jede Nachlässigkeit, jede 'Vereinfachung' rächt sich irgendwann. Das war 
noch immer so und wird auch immer so sein.

von Heinz (Gast)


Lesenswert?

Luky, du musst deine Aufgabenstellung schon genauer beschreiben. Z. B. 
wie viel Zeit du hast oder wie viele Eingänge deiner 3 Ports wie 
umsortiert werden müssen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Man könnte natürlich einfach die Daten "unsortiert" abgreifen und dann 
einfach bei der Auswertung sortieren...

von Luky (Gast)


Lesenswert?

Das Layout ist nicht von mir (und u.A. durch den zweilagigen Aufbau 
bedingt), die Zeitanforderung ist wie bereits geschrieben "so schnell 
wie möglich" und ich muss von 3 Ports ALLE Bits umsortieren. Kann 
vorkommen, dass 2-4 in einer Reihe liegen, aber nicht an der richtigen 
Stelle.
Also suche ich eine Möglichkeit wie ich Ein Bit von einer stelle in 
einer Variablen möglichst schnell auf eine Stelle einer anderen Variable 
schreiben kann.

von Peter D. (peda)


Lesenswert?

Luky schrieb:
> Die Umwandlung IST zeitkritisch, da sie direkten Einfluss auf die
> maximal mögliche Abtastrate hat. Je schneller die Umwandlung, desto mehr
> Messungen können durchgeführt werden.

Wayne interessierts.
Wichtig ist allein die Abtastrate, die in der Spezifikation gefordert 
wurde.

Wenn aber keine Spezifikation erstellt wurde, dann ist das Projekt 
grundsätzlich falsch gelaufen.
Man baut ja auch kein Haus, ohne vorher zu wissen, wieviel Zimmer es 
haben soll.


Peter

von Peter II (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Man baut ja auch kein Haus, ohne zu wissen, wieviel Zimmer es haben
> soll.

doch ist sogar bei Büros sehr üblich, der Mieter legt erst später die 
Räume fest.

Wo ist dann das Problem, er will es so schnell wie möglich haben - das 
ist doch einfach nur eine Aufgabe.

von spess53 (Gast)


Lesenswert?

Hi

>Also suche ich eine Möglichkeit wie ich Ein Bit von einer stelle in
>einer Variablen möglichst schnell auf eine Stelle einer anderen Variable
>schreiben kann.

Wenn du Assembler nicht scheust: Mit den Befehlen bld und bst ist ein 
Bit in 2 Takten an einer beliebigen Stelle in einem beliebigen Register.

MfG Spess

von Peter D. (peda)


Lesenswert?

Peter II schrieb:
> Wo ist dann das Problem, er will es so schnell wie möglich haben - das
> ist doch einfach nur eine Aufgabe.

Nö, ist nur ne Methode, sich selber das Leben schwer zu machen. Die 
eierlegende Wollmilchsau wird niemals fertig.

Bei einem richtigen Projekt rechnet man sogar noch ne Reserve ein. Man 
nimmt das 2..10-fache der Spezifikation und rechnet es durch. Denn 
oftmals gibt es noch Faktoren, die man nicht berücksichtigt hat und dann 
ist man froh über die Reserve. Oder der Kunde hat sich vertan mit seinen 
Vorgaben.


Peter

von Luky (Gast)


Lesenswert?

Danke an spess53 für den echt hilfreichen Tipp. War genau das, was ich 
gesucht habe und löst meine Probleme.

Peter Dannegger kann wirklich lästig und nicht besonders hilfreich (im 
Gegenteil!!) sein, auch wenn man explizit schreibt dass die 
Aufgabenstellung nicht Teil der Frageist.
Ein echter Grund, dieses Forum tendenziell zu meiden :-(
Wenn jemand eine konkrete Frage hat, nütz es niemanden, an der 
Aufgabenstellung herummzuklugscheißern... Denk mal darüber nach!

von Peter II (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Nö, ist nur ne Methode, sich selber das Leben schwer zu machen. Die
> eierlegende Wollmilchsau wird niemals fertig.

wenn ich am PC ein Programm schreibe soll es auch so schnell wie möglich 
sein. Ich will aber keinen schnelleren PC.

Seine Anwendung geht vielleich auch langsamer, aber er möchte das es 
halt schneller ist - es ist einfach so!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Luky schrieb:
> Ein echter Grund, dieses Forum tendenziell zu meiden :-(
Blöd nur, dass du hier trotzdem am schnellsten ein nutzbringende Antwort 
bekommst...

> Wenn jemand eine konkrete Frage hat, nütz es niemanden, an der
> Aufgabenstellung herummzuklugscheißern...
Manche machen Fehler öfter, weil man sie nicht explizit auf die Ursache 
hinweist...
> Denk mal darüber nach!
Ja, so ist das.

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Wenn du Assembler nicht scheust: Mit den Befehlen bld und bst ist ein
> Bit in 2 Takten an einer beliebigen Stelle in einem beliebigen Register.

Ist genau gleich schnell, wie testen des Pins und setzen des Zielbits.
Allerdings macht der AVR-GCC einige unnütze Befehle, wenn man das in C 
schreibt. Ist dann ne Abwägung zwischen gut lesbar und portabel oder 2-3 
Zyklen gespart.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Luky schrieb:

> Gegenteil!!) sein, auch wenn man explizit schreibt dass die
> Aufgabenstellung nicht Teil der Frageist.

Hier liegst du falsch.
In der Softwareentwicklung ist die Aufgabenstellung praktisch immer Teil 
der Frage. Aber dann schon eine richtige Aufgabenstellung und nicht 'so 
schnell wie möglich'.

> Ein echter Grund, dieses Forum tendenziell zu meiden :-(

Es steht dir frei, genau das zu tun.

> Wenn jemand eine konkrete Frage hat, nütz es niemanden, an der
> Aufgabenstellung herummzuklugscheißern... Denk mal darüber nach!

Wenn du wüsstest, wie oft hier Typen aufschlagen, mit irgendwelchen 
windigen Vorgaben und 'konkreten' Vorstellungen wie ein Problem zu lösen 
sein wird. Und wenn man dann geduldig nachbohrt, stellt sich raus, dass 
er das komplett falsche Teilproblem löst. Verändere die 
Ausgangssituation ein wenig und sein Teilproblem löst sich in Luft auf.

Alles schon gehabt. Mehrfach und immer wieder.

von Rolf Magnus (Gast)


Lesenswert?

Luky schrieb:
> Wenn jemand eine konkrete Frage hat, nütz es niemanden, an der
> Aufgabenstellung herummzuklugscheißern... Denk mal darüber nach!

Doch, denn wenn die Frage auf einen Fehler in der Aufgabenstellung 
schließen läßt, muß man diese erstmal prüfen und ggf. anpassen, damit 
eine sinnvollere Frage rauskommt.

Du wolltest es "so schnell wie möglich". Das wäre die Tabelle. Dafür 
willst du aber nicht den Speicherverbrauch hinnehmen. Also wird schon 
mal "so schnell wie möglich, ohne dabei viel Speicher zu verbrauchen" 
draus. Das ist jetzt nicht präziser, sondern ganz im Gegenteil.
Für einen nächsten Lösungsansatz müßte man exakt wissen, welche Bits 
genau von wo nach wo geschoben werden müssen. Dann kann man sich eine 
handoptimierte Assembler-Variante überlegen, die die wenigstmöglichen 
Taktzyklen für genau diesen Anwendungsfall braucht. Ob dir das am Ende 
wirklich was bringt, weiß aber keiner, weil die Aufgabenstellung schon 
nicht klar definiert war.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

Wenn der µC die passenden Befehle hat kann man auch über den 
Program-Counter an eine Stelle springen an der dann wiederum das 
entsprechende Byte in einem Arbeitsregister übergeben wird. Bei PIC's 
ist das sehr einfach möglich, keine Ahnung ob der AVR das ebenfalls 
kann, denke aber schon. Bedingung ist das die Rückgabe mit Wert in einem 
Befehlswort erfolgen kann. Beim PIC ist das eben der RETLW Befehl.

Man macht nun eine "Tabelle" mit 256 RETLW's der entsprechenden Werte. 
Direkt vor der Tabelle macht man dann einen relativen Sprung, wobei die 
Sprungweite dann eben der Einganswert ist. Zurück kommt dann der 
gewünschte Ausgabewert im W Register.

Diese Methode kann schneller sein als der Zugriff über eine Tabelle im 
Flash, das hängt aber davon ab was der jeweilige µC an Befehlen anbietet 
um auf den Flash zuzugreifen und wie lange diese brauchen. Wie gesagt, 
ich weiss nicht was der AVR da so anbietet, da ich selber nur PIC's 
benutze, und auf denen lässt sich das mit genannter Methode sehr 
effizient realisieren.

Grüße,

Chris

von Optimierer (Gast)


Lesenswert?

Luky schrieb:
> Danke an spess53 für den echt hilfreichen Tipp. War genau das, was ich
> gesucht habe und löst meine Probleme.
>
> Peter Dannegger kann wirklich lästig und nicht besonders hilfreich (im
> Gegenteil!!) sein, auch wenn man explizit schreibt dass die
> Aufgabenstellung nicht Teil der Frageist.
> Ein echter Grund, dieses Forum tendenziell zu meiden :-(

Lieber Luky,
du hast hier von einem halben Dutzend Leuten hilfreiche Tipps gekriegt 
bevor du es geschafft hast wenistens EINEM mal DANKE zu sagen.
Vieleicht sollte man deine Aussage folgendermaßen umformulieren:

Man sollte sich überlegen hier noch Leuten zu helfen, denn in der Regel 
bekommt man kein Danke und wird sogar noch blöd angemacht wenn man sie 
auf Fehler/Schwächen in ihrem Design hinweist!

In diesem Sinne: Der Fehler sitzt immer vor der Tastatur!

von Εrnst B. (ernst)


Lesenswert?

Christian Klippel schrieb:
> da ich selber nur PIC's
> benutze, und auf denen lässt sich das mit genannter Methode sehr
> effizient realisieren.

Diese Methode ist IIRC nur bei den PICs wirklich sinnvoll. Die PICs 
verwenden breitere Befehltsworte (12 Bit, 14 Bit), da passt ein RET + 
Bytewert in einen Befehl, es wird kein Speicherplatz verschwendet.

Die AVRs haben ihren Programmcode byteweise. Da würde die RET + Wert 
-Tabelle viel Speicherplatz verschwenden. Macht nix, stattdessen kann 
man die Tabelle, nur mit Werten gefüllt in den Flash legen, und kommt 
mit einem "LPM" aus.

von Optimierer (Gast)


Lesenswert?

Christian Klippel schrieb:
> Man macht nun eine "Tabelle" mit 256 RETLW's der entsprechenden Werte.
> Direkt vor der Tabelle macht man dann einen relativen Sprung, wobei die
> Sprungweite dann eben der Einganswert ist. Zurück kommt dann der
> gewünschte Ausgabewert im W Register.

Clever :-)
aber wehe wenn du so einen Code in einem undokumentierten Projekt 
verstehen musst: WÜRG

von Mark B. (markbrandis)


Lesenswert?

Unclear requirements: Killing software projects since the 1950s.

von Christian K. (Firma: Atelier Klippel) (mamalala)


Lesenswert?

@ernst:

Ah, Danke für die Info, wusste ich nicht das der Programcode bei den 
AVR's Byteweise abgelegt ist, und nicht in ganzen Befehlsworten. Die 
PIC18XXX haben ja zum Glück direkt Befehle um aus RAM und Flash zu 
lesen, mit Auto-Increment/Decrement/etc. der zu lesenden Adresse...

@Optimierer:

Naja, so "Clever" ist das nicht einmal, zumindest nicht von mir. Das 
steht nämlich auch so in den Datenblättern, nennt sich "Computed GOTO". 
Erkennt man auch sofort wenn man sowas sieht ;)

Damit lassen sich auch noch andere feine Sachen anstellen, z.B. switch() 
Blöcke stark optimieren, unter gewissen Voraussetzungen. Verwende sowas 
sehr oft und gerne bei zeitkritischen Stellen.

Denke mal das die AVR's da aber ähnliches anbieten, würde mich zumindest 
wundern wenn nicht.

Grüße,

Chris

von Peter II (Gast)


Lesenswert?

Christian Klippel schrieb:
> Denke mal das die AVR's da aber ähnliches anbieten, würde mich zumindest
> wundern wenn nicht.

geht dort genauso, man kann einfach den switch wert * 2 rechnen dann hat 
man platz für das ret.

von Thomas E. (thomase)


Lesenswert?

Εrnst B✶ schrieb:
> Die AVRs haben ihren Programmcode byteweise.
Nein. Das Flash ist 16 Bit breit.

mfg.

von Εrnst B. (ernst)


Lesenswert?

Thomas Eckmann schrieb:
>> Die AVRs haben ihren Programmcode byteweise.
> Nein. Das Flash ist 16 Bit breit.

 OK, der Programmcounter läuft auf 16-Bit-Speicherstellen, aber LPM 
arbeitet trotzdem Byteweise.

>>Da würde die RET + Wert -Tabelle viel Speicherplatz verschwenden.
> Unsinn. Selbst wenn es so wäre, würde das lediglich 2 Lesezugriffe
> bedeuten.

Im AVR-Progmem kann ich pro 8 Bit vorhandenem Flash ein Byte 
Tabelleninhalt (für LPM) ablegen.
d.h. Pro 16-Bit Wort zwei Bytes.

Mit der Ret+Wert Konstruktion krieg ich pro 16Bit-Wort nur ein Byte 
Tabelleninhalt unter.

Hab ich irgendwas übersehen (außer dass du deinen Post editiert hast, 
während ich am Antwort-Schreiben war)?

von spess53 (Gast)


Lesenswert?

Hi

>Nein. Das Flash ist 16 Bit breit.

Jain. Befehle sind 16 Bit bzw. ein Vielfaches von 16 Bit breit. Aber auf 
z.B. Tabellen kann auch byteweise zugegriffen werden.

MfG Spess

von Rolf Magnus (Gast)


Lesenswert?

Εrnst B✶ schrieb:
> Thomas Eckmann schrieb:
>>> Die AVRs haben ihren Programmcode byteweise.
>> Nein. Das Flash ist 16 Bit breit.
>
> Naja, OK, der Programmcounter läuft auf 16-Bit-Speicherstellen, aber LPM
> arbeitet trotzdem Byteweise.

Ja. LPM schiebt die übergebene Adresse quasi um ein Bit nach rechts und 
verwendet das "herausgefallene" Bit, um die Hälfte der Speicherstelle zu 
wählen, die gelesen werden soll.

> Im AVR-Progmem kann ich pro 8 Bit vorhandenem Flash ein Byte
> Tabelleninhalt (für LPM) ablegen.
> d.h. Pro 16-Bit Wort zwei Bytes.
>
> Mit der Ret+Wert Konstruktion krieg ich pro 16Bit-Wort nur ein Byte
> Tabelleninhalt unter.
>
> Hab ich irgendwas übersehen?

Nein, das ist so. Abgesehen davon gibt es keinen Ret mit Wert beim AVR.

von bgm (Gast)


Lesenswert?

Zum Sortieren von Bits kann ich folgendes empfehlen:

1
unsigned int i, j; // positions of bit sequences to swap
2
unsigned int n;    // number of consecutive bits in each sequence
3
unsigned int b;    // bits to swap reside in b
4
unsigned int r;    // bit-swapped result goes here
5
6
unsigned int x = ((b >> i) ^ (b >> j)) & ((1U << n) - 1); // XOR temporary
7
r = b ^ ((x << i) | (x << j));

Zum Beispiel:
b = 00101111 (binär)
und wir wollen 3 aufeinander folgende Bits swappen
n = 3
beginnend beim 2. Bit von rechts:
i = 1
an die 5. Stelle
j = 5
Ergenbnis:
r = 11100011 (binär)


Quelle: 
http://graphics.stanford.edu/~seander/bithacks.html#SwappingBitsXOR

MfG,
bgm

von Peter D. (peda)


Lesenswert?

Christian Klippel schrieb:
> Wie gesagt,
> ich weiss nicht was der AVR da so anbietet, da ich selber nur PIC's
> benutze, und auf denen lässt sich das mit genannter Methode sehr
> effizient realisieren.

Na effizient ist das nicht gerade, wenn der Befehl 14 Bit lang ist, 
gehen Dir pro Byte 6 Bit flöten.

Das RETLW ist auch nicht sonderlich komfortbel, wenn die Daten eine 
Pagegrenze überschreiten, mußt Du noch die Pagenummer berechnen.

Es ist eher ein Würg-Around, weil die älteren PICs keinen Zugriffsbefehl 
auf den Flash hatten.
Die neueren haben ihn aber, weil es damit bedeutend einfacher und 
effektiver ist, Daten vom Flash zu lesen.

Die AVRs haben ihn auch (LPM), daher haben die AVRs kein RETLW nötig.


Peter

von superstru (Gast)


Lesenswert?

ich hatte mich auch mal verlötet, und 8 bit verkehrt herum angelötet.

http://graphics.stanford.edu/~seander/bithacks.html wie weiter oben war 
inspirativ, immer wieder empfehlenswert. aber dennoch half nur eines 
wirklich gut: alte verbindungen kappen, neue brücken setzen. war mal 
wieder ne lehre :D

von Frank S. (herrschrader)


Lesenswert?

Die frühen PICs waren noch sehr auf Sicherheit bedacht.
Durch den RETLW konnte man zwar Daten- und Sprung-Tabellen im Flash 
ablegen, aber es gab keinen anderen Befehl um den Flash auszulesen. So 
konnte selbst ein Bug im Programm nicht ausgenutzt werden, um den 
Flash-Inhalt zu lesen.
Sicherheitstechnisch ein tolles Feature. Ob so geplant oder nur zufällig 
entzieht sich meiner Kenntnis.

von Peter D. (peda)


Lesenswert?

superstru schrieb:
> ich hatte mich auch mal verlötet, und 8 bit verkehrt herum angelötet.

Ist mir auch mal passiert.
Im Kleingedruckten des Datenblattes stand D1 (MSB) ... D8 (LSB). Damit 
war die Verpolung quasi eingeplant. Jeder Mensch denkt ja, daß die 
niederwertige Leitung das LSB ist.

War aber für ein Text-Display, da spielt die Zeit keine Rolle. Habs also 
mit 8 mal links/rechts Schieben gedreht.


Peter

von Michael S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allemiteinander,

um einen konstruktiven Beitrag zum genannten Problem zu leisten:

Ich habe es (wie oben von spess erwähnt) mit BLD und BST in Assembler 
gelöst.
Die Funktion get_portb_reversed() liest alle Bits von PORTB ein, 
vertauscht die Reihenfolge (nur zur Demonstration) und liefert das 
Ergebnis zurück.

Das Prinzip:

in  R25, _SFR_IO_ADDR(PORTB) // PORTB nach R25 laden

clr R24                      // das Zielregister löschen,
                             // R24 gibt das Ergebnis zurück

bld R25, 0                   // Bit.0 von PORTB ins T-Flag laden
bst R24, 7                   // und das T-Flag nach Bit.7 von R24 
kopieren

bld R25, 1                   // Bit.1 von PORTB ins T-Flag laden
bst R24, 6                   // und das T-Flag nach Bit.6 von R24 
kopieren

.........                    // und so weiter mit den anderen Bits

Das vollständige Programm (ungetestet!) hänge ich mal an.
Knapper geht's vermutlich nicht.

Oder doch ?
Das pushen und popen kann man wohl noch einsparen.

mfg

Michael S.

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.