Gast
#2254258
Wie kann man am besten so "mal eben" ein Bit invertieren, um es so an einem Port auszugeben?! Also aus 11101010 mach 01010111
|
Anzeige
|
bit invertieren
Gast
#2254258
Wie kann man am besten so "mal eben" ein Bit invertieren, um es so an einem Port auszugeben?! Also aus 11101010 mach 01010111
Gast
#2254260
hugo schrieb: > 11101010 11101010 xor 11111111 xor passend zu deiner Programmiersprache suchen Das ist aber kein Bit, welches invertiert wird, sondern ein Byte, was gespiegelt wird. hugo schrieb: > Wie kann man am besten so "mal eben" ein Bit invertieren, um es so an > einem Port auszugeben?! > Also aus 11101010 mach 01010111 Das ist ein invertiertes BYTE... :-o Und das gabs schon oft hier im Forum. Die Suche wird dir helfen... http://www.mikrocontroller.net/search?query=Byte+spiegeln&forums[]=1&forums[]=2 EDIT: Mist, Fenster zu lang offen... :-/
Gast
#2254278
Ein einzelnes Bit kannst di ändern wie im Video gezeigt: http://et-tutorials.de/1908/bitweise-manipulation/ ET-Tutorials schrieb: > Ein einzelnes Bit kannst di ändern Thema verfehlt... ;-)
Gast
#2254295
CPL Werden immer die selben Bits invertiert? Dann z.B. mit einer Bitmaske! Viele Grüße
Gast
#2254402
falls du einen xmega verwendest: PORTx.OUTTGL = 0xFF; (alle Bits im Ausgangsregister toggeln) ich schrieb: > PORTx.OUTTGL = 0xFF; (alle Bits im Ausgangsregister toggeln) Christian W. schrieb: > Werden immer die selben Bits invertiert? > Dann z.B. mit einer Bitmaske! Stephan schrieb: > CPL An alle drei: Thema verfehlt. Lest mal, was hugo schrieb: > Also aus 11101010 mach 01010111 Lothar Miller schrieb: > Lest mal, was > hugo schrieb: >> Also aus 11101010 mach 01010111 hugo schrieb aber auch: > Wie kann man am besten so "mal eben" ein Bit invertieren, um es so an > einem Port auszugeben?! Offensichtlich weiß er selbst nicht was er will und weiß auch nicht was ein Bit und was ein Byte ist. J.-u. G. schrieb: > Offensichtlich weiß er selbst nicht was er will und weiß auch nicht was > ein Bit und was ein Byte ist. Das geht offenbar vielen so, die das nicht wissen... ;-) Nochmal der Link zur Suche, da sind auch ein paar solcher Kandidaten: > Lothar Miller schrieb: >> Die Suche wird dir helfen... >> http://www.mikrocontroller.net/search?query=Byte+spiegeln Und weil er es selbst nicht weiß, was er will, es aber beschreiben kann, gilt die Regel:
>> Also aus 11101010 mach 01010111
Nicht ausprobiert, deshalb ohne Gewähr ;-) Grüsse
Gast
#2255365
Okay, Ihr habt Recht, ich wusste nicht genau was ich wollte :D. Also ich will das Byte natürlich Spiegeln. Und das am besten in C. Es war gestern glaub einfach schon zu spät xD
Ohne Gewähr. Volker
Ist eleganter als oben. Diesmal mit Gewähr, habe es im Simulator getestet :-) Es ist zwar C gefragt, aber vielleicht braucht es ja mal jemand in ASM.
Gast
#2255533
IMHO ist in C eine Tabelle das Schnellste. MfG Klaus Warum schiebst du vor "lop" eine 1 in r16 rein? hugo schrieb: > Und das am besten in C. Mit meinem Link zur Forumssuche hättest du das gefunden: Beitrag "Re: reihenfolge der bits in einem byte umdrehen" Michael Dierken schrieb: > Warum schiebst du vor "lop" eine 1 in r16 rein? R16 ist solange <>0 bis die 1 im Carry ist. Solange springt dann brne. Man spart so den Schleifenzähler und ein paar Zyklen.. Klaus schrieb: > IMHO ist in C eine Tabelle das Schnellste. wenn man soviel Speicher übrig hat Sascha Sascha Weber schrieb: > Klaus schrieb: >> IMHO ist in C eine Tabelle das Schnellste. > wenn man soviel Speicher übrig hat 16 Byte reichen dafür. Die Nibbles kann man swappen. http://en.wikipedia.org/wiki/Bit-reversal_permutation "Bit reversal is most important for radix-2 Cooley–Tukey FFT algorithms" nur um den englischen Begriff auch mal zu nennen
Gast
#2255756
Folgender Code auch recht effizient compiliert...
Peter schrieb: > Folgender Code auch recht effizient compiliert... Stimmt! Obwohl er recht lang aussieht, sind es nur 178 Byte erzeugter Code beim avr-gcc - inkl. leerer main-Funktion: Program: 178 bytes (1.1% Full) Data: 0 bytes (0.0% Full) Da habe ich das mal eben mit einer Tabelle ausprobiert:
Ergebnis: Program: 266 bytes (1.6% Full) Data: 16 bytes (1.6% Full) Das Programm "sieht" zwar kürzer aus, kostet aber doch einiges mehr an Speicherplatz... Zuallerletzt habe ich Volkers Version getestet (mit kleinen Modifikationen, z.B. int -> uint8_t):
Ergebnis: Program: 162 bytes (1.0% Full) Data: 0 bytes (0.0% Full) Damit liegt Volkers Version derzeit an der Spitze, was die Sparsamkeit an Speicherplatz angeht. Beim Austesten stellte ich fest, dass Volkers Version einen Fehler hat. Es fehlte das unterste Bit im Ergebnis. Hier die korrigierte Version:
Die Zeile "out <<= 1" musste lediglich vor das if-Statment gezogen werden. Es bleibt aber bei 162 Bytes an Code. Und noch ne Funktion:
Grüße, Michael
Gast
#2255878
Volkers Version ist etwas kürzer, dafür etwas langsamer bei der Ausführung. Bleibt beim Anwender zu entscheiden was für ihn wichtiger ist, Code-Size oder Code-Speed! ;o)
Gast
#2255883
Lothar Miller schrieb: > Lest mal, was > hugo schrieb: >> Also aus 11101010 mach 01010111 Es geht doch nichts über einen passenden Titel. Warum sagt er dann nicht gleich "Byte spiegeln" oder Bitfolge invertieren. Invertieren bezogen auf ein Bit ist immer noch der Not-Operator. Hier mal ein Zwischenstand. Der Speicherbedarf wurde ermittelt, indem vorneweg alles mit mirror auskommentiert wurde, und danach der Speicherplatzzuwachs festgestellt wurde (Atmega32, -Os, avr-gcc 4.3.2):
Komisch schrieb: > Es geht doch nichts über einen passenden Titel. Warum sagt er dann nicht > gleich "Byte spiegeln" oder Bitfolge invertieren. Vielleicht, weil ihm der Begriff nicht geläufig war... Michael K. schrieb: > Und noch ne Funktion: > >
Stimmt, die habe ich hier auf µC.net auch schon öfters rumschwirren sehen. Ergebnis: Program: 180 bytes (1.1% Full) Data: 0 bytes (0.0% Full) Das ist dann der 3. Platz... aber knapp :-) Lothar Miller schrieb: > uint8_t mirror (uint8_t val) // 208 Bytes Frank M. schrieb: > Program: 180 bytes (1.1% Full) Ich muß mal meinen Compiler updaten... ;-) Lothar Miller schrieb: > Hier mal ein Zwischenstand. Der Speicherbedarf wurde ermittelt, indem > vorneweg alles mit mirror auskommentiert wurde, und danach der > Speicherplatzzuwachs festgestellt wurde (Atmega32, -Os, avr-gcc 4.3.2): Erstaunlich, was bei Dir an relativen(!) Unterschieden rauskommt. Bei mir ist es ATmega168, -Os, avr-gcc 4.3.3. Lothar Miller schrieb: > Lothar Miller schrieb: >> uint8_t mirror (uint8_t val) // 208 Bytes > Frank M. schrieb: >> Program: 180 bytes (1.1% Full) > Ich muß mal meinen Compiler updaten... ;-) Da ist ein leeres main() auch mit drin. Das halte ich für legitim, da der Compiler auch bei Nicht-Aufruf die Funktionen NICHT wegoptimieren kann, da sie nicht als static deklariert sind. Wie ist das bei Dir? Zählst Du Deine (aufwendigere) main-Funktion mit? EDIT: Bei mir frisst die leere main-Funktion 138 Byte, die müsste man also von meinen Werten abziehen. Dann sieht der 4.3.3er Compiler um einiges besser aus als Dein 4.3.2er.
Gast
#2255927
hübsche sammlung von verschiedenen ansätzen zum bitreihenfolge invertieren: http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious geht als schleife, mit arrays, und ein paar andere "hacks". die ganzen tipps da sind öfters recht praktisch. Frank M. schrieb: > Wie ist das bei Dir? So sieht die "leere" main aus:
Ich glaube wir haben Hugo (TO) etwas überfordert. Er meldet sich gar nicht mehr! Hallo Huuuugooooo. Konten wir dir helfen oder haben wir dich nur verwirrt? volker
Gast
#2256714
Das ist ja echt der Wahnsinn xD Ihr ward echt seeehr krass... Naja das ganze ist so: Ich hab ein Display und das hängt direkt an einem Port. Aus Layout technischen Gründen müsste ich ALLE Leitungen kreuzen, was natürlich ziemlich dumm ist. Jetzt habe ich überlegt einfach immer das Byte zu spiegeln, damit ich es so übertragen kann. Ich denke aber bei einem Grafik LCD ist das totaler Quatsch, da der AVR ja 2/3 seiner Zeit nur damit verbringt Daten zu spiegeln. Da er später noch andere Dinger erledigen soll wäre das also dumm. Nun bin ich am Überlegen einen SMD-Stecker zu nehmen, dann kann ich die Leiterbahnen von oben anfahren (kann Zuhause nur einseitige Platinen mit min. 8mil Leiterbahnen). Aber ich finde diesen Thread echt klasse! Wenn wir nun vielleicht alles zusammenstellen und irgendwo festhalten wär das schonmal toll! Danke euch!
Gast
#2256850
Anbei die reine Codegrösse für die Funktionen und die Anzahl CPU-Zyklen für die Verarbeitung (Function Call bis Return) Bei mirror4() habe ich den Array auf static gesetzt, dann werden dessen Werte nur einmal im StartUpCode initialisiert und nicht bei jedem Funktions-Aufruf. (Codesize und CPU-Zyklen für diese Initialisierung sind nicht dabei)
Peter schrieb: > Anbei die reine Codegrösse für die Funktionen und die Anzahl CPU-Zyklen > für die Verarbeitung (Function Call bis Return) Welche avr-gcc-Version? Welche Optimierungsstufe? Wie wir gestern gesehen haben, gibt es allein bei der Version erhebliche Unterschiede im Ergebnis. > Bei mirror4() habe ich den Array auf static gesetzt, dann werden dessen > Werte nur einmal im StartUpCode initialisiert und nicht bei jedem > Funktions-Aufruf. Ohja, das hatte ich doch glatt übersehen. Damit liegt mirror4 mit der Ausführungszeit an erster Stelle und vom Speicherplatz immerhin noch an 2. Stelle. Interessant, dass mirror3() als kleinste Funktion auch die langsamste ist. Danke für die Aufstellung. Gruß, Frank
Gast
#2257035
Also das ist ja super! Wo speichern wir das jetzt ab?! ;-)
Gast
#2257086
hugo schrieb: > Also ich will das Byte natürlich Spiegeln. Und das am besten in C. Na, wenn nicht ausschließlich C, dann hat auch noch 'ne Bascom-Version Platz ;D
40Bytes, 20 Cycles. MWS schrieb: > dann hat auch noch 'ne Bascom-Version Platz ;D > !LDS R16, {Var_In} > !BST R16, 0 Naja. Ich würde sagen, das fällt fast schon unter "Assembler-Doping"... > 40Bytes, 20 Cycles. Das ist jetzt aber noch keine richtige Unterroutine... >> Peter schrieb: >>> Anbei die reine Codegrösse für die Funktionen und die Anzahl CPU-Zyklen >>> für die Verarbeitung (Function Call bis Return) hugo schrieb: > Das ist ja echt der Wahnsinn xD > Ihr ward echt seeehr krass... > Naja das ganze ist so: Ich hab ein Display und das hängt direkt an einem > Port. Aus Layout technischen Gründen müsste ich ALLE Leitungen kreuzen, > was natürlich ziemlich dumm ist. Jetzt habe ich überlegt einfach immer > das Byte zu spiegeln, damit ich es so übertragen kann. Ich denke aber > bei einem Grafik LCD ist das totaler Quatsch, da der AVR ja 2/3 seiner > Zeit nur damit verbringt Daten zu spiegeln. Da er später noch andere > Dinger erledigen soll wäre das also dumm. Bei der Initialisierung des GLCD kann man auch entsprechende Konstante nehmen (und das kommentieren), die Fonts zur Textausgabe lassen sich auch vorher spiegeln/passend generieren und die Routinen zum Pixel-Setzen/Linien-Zeichnen kann man auch passend schreiben...
Gast
#2257179
Lothar Miller schrieb: > Naja. Ich würde sagen, das fällt fast schon unter "Assembler-Doping"... Da hast Du natürlich recht, da sich aber Assembler bei Bascom äußerst problemlos in Basic-Code einbetten lässt, so ist das legitim. > Das ist jetzt aber noch keine richtige Unterroutine... Das sind sie im C-Beispiel auch nicht. Nur mirror2 wird über einen CALL aufgerufen, alles andere wird vom Compiler Inline eingebaut (mit -Os). Und zwar wiederholt, zweimal mirror1 aufgerufen wird auch zweimal als Inline compiliert. Wahrscheinlich weil bei der kleinen Codegröße der Funktion der Overhead unrentabel ist. >>>> Anbei die reine Codegrösse für die Funktionen und die Anzahl CPU-Zyklen >>>> für die Verarbeitung (Function Call bis Return) Eine Bascom-Sub, die auch tatsächlich als Sub eingebunden ist, benötigt dann 39 Cycles, liegt daran, daß die Variablenzeiger auf den Frame gehen/von dort geholt werden müssen.
Gast
#2257231
Also die Bascom Variante von MWS (Gast) gefällt mir doch sehr. Wie könnte ich das auf C übertragen? Geht das in C überhaupt, Werte an Assembler zu übergeben und zurückzubekommen?
Gast
#2257274
Räuber Hotzenplotz schrieb: > Wie könnte ich das auf C übertragen? Sollte per Inline Assembler gehen, ist aber im Vergleich zu dem Gezeigten relativ kompliziert, der C-Compiler hat's nicht gern, wenn man sich einmischt. Vorteil meiner Version ist die völlig freie Bitzuweisung, somit lassen sich einfach die Anschlüsse intern "umverdrahten". So entstand dieser Codeteil auch, wurde in ein Lib eingebunden um entsprechend einem anderes Platinenlayout für ein Display mit einem I2C-Expander PCF8574 die Pins frei zuweisen zu können. MWS schrieb: > Das sind sie im C-Beispiel auch nicht. Nur mirror2 wird über einen CALL > aufgerufen, alles andere wird vom Compiler Inline eingebaut (mit -Os). Das schon. Aber die Aufrufparameter sind frei wählbar. > Eine Bascom-Sub, die auch tatsächlich als Sub eingebunden ist, benötigt > dann 39 Cycles Liegt damit annähernd gleichauf zur Lösung mirror2, wo ja auch beliebige Bits zugeordnet werden könnten.
Gast
#2257565
Lothar Miller schrieb: > Das schon. Aber die Aufrufparameter sind frei wählbar. Wenn man Speed braucht, dann ist's egal, ob die Aufrufparameter frei wählbar sind. Speziell für den Fall eine Pinbelegung "umzubiegen" wird dieser Codeblock in die ausgebende Funktion eingebaut, da brauch' ich keinen Call auf eine Funktion machen, und dann sind wir wieder bei 20 Takten. Da beißt die Maus keinen Faden ab. MWS schrieb: > Da beißt die Maus keinen Faden ab. Es ging ja nicht um den Faden der Maus, sondern um die Vergleichbarkeit... ;-)
Gast
#2257632
Lothar Miller schrieb: > Es ging ja nicht um den Faden der Maus, sondern um die > Vergleichbarkeit... ;-) Ja, und mir ging's um die Verwendbarkeit im Sinnes des TEs :D
Gast
#2257661
Um auch das noch zu beantworten: Räuber Hotzenplotz schrieb: > Wie könnte ich das auf C übertragen? > Geht das in C überhaupt, Werte an Assembler zu übergeben und > zurückzubekommen?
Gast
#2258722
@MWS (Gast): Ganz vielen Dank für die Mühe! :-) : [out_reg] "=&r" (out), [in_reg] "+r" (in) verstehe ich nicht so ganz (bin Anfänger in C ) Werde es am Montag testen, wenn ich wieder in der "Firma" bin ;-) Hoffentlich geht das mit AVRStudio4 und WINAVR... Ich wär so froh :-)
Gast
#2258730
Räuber Hotzenplotz schrieb: > : [out_reg] "=&r" (out), [in_reg] "+r" (in) > verstehe ich nicht so ganz Nennt sich "clobber list". Ich fand's interessant wie's dem Compiler beizubringen ist, mach' normalerweise nichts in C-asm. Du kannst übrigens auch mirror2 nehmen, da wird sehr schöner und kurzer Code erzeugt. Funktional ist's gleich. Hallo Räuber, :-) ich habs mal kurz für Dich getestet, damit Du am Montag beruhigt in die Firma fahren kannst:
Getestet mit AVR-Studio 4.18 (Build 716) / Amtel 8515 Simulator, lässt sich einwandfrei compilieren! Gruß Markus Und warum Inline-Assembler???
Belegt nur 2 Register, das Input-Register bleibt erhalten und braucht 19 Ticks + RET (deviceabhängig), hier avr-gcc 4.6.1:
In Assembler geht auch
Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|