Hallo,
Ich hab eine kleine Verständnisfrage zur Bitverschiebung.
Und zwar will ich ein Byte(8bits) aus einem Rechtecksignal
vollschreiben.
definition:
1
volatileintzahl=0;
2
volatileintbit;
3
volatileintbit_z;
In der Main:
1
zahl|=(bit<<bit_z);
(bit_z wird danach inkrementiert und wenn er bei 8 ist, wieder auf 0
gesetzt und das byte beschrieben, so sollte quasi das Byte voll sein)
Nachdem, was ich verstanden habe, sollte doch von rechts angefangen
werden(also bit_z = 0) und dann immer einen weiter nach links.
Das Problem ist, das ich jedoch zb wenn normal 6 rauskommen sollte, 96
rauskommt. Ist es dann also doch umgekehrt?
Was heißt "wenn normal 6 rauskommen sollte"? Das niederwertigste Bit
(Wert 1) ist das ganz rechte, das beschreibst Du als erstes. Das links
daneben hat Wert 2, das nächste Wert 4 usw.
Wenn der Wert 6 rauskommt, waren das 2. und 3. empfangene Bit 1 und die
anderen 0.
Dein Algorithmus ist übrigens auf einem Mikrocontroller ohne
Barrel-Shifter ziemlich ineffizient. Besser wäre:
1
zahl=(zahl<<1)|bit;
Dann ist es aber wirklich "umgekehrt", weil das Bit dann mit jedem
Durchgang eine Stelle weiter nach links rückt. Das erste empfangene Bit
steht am Ende also ganz links. Kommt halt drauf an, wie Du es haben
willst/brauchst.
Die volatiles sind sicher auch nicht alle nötig.
Die volatiles habe ich wegen einem interrupt und sollten überall
vorhanden sein, also im interrupt und main(oder ist das falsch?)
Also ich sollte aus einem Rechtecksignal theoretisch die 6 bekommen,
daher die 6.
Das Rechtecksignal kommt so an:
01100000 (Im Rechtecksignal)
Müsste also quasi wenn von rechts nach links anfängt in das Byte zu
schreiben so da stehen:
00000110 also 6.
Jedoch ist es genau wie in der Rechtecksignal
01100000 also 96.
Was ist ein Barrel-shifter??
Danke schonmal für die Antwort ;)
Em Gr schrieb:> Die volatiles habe ich wegen einem interrupt und sollten überall> vorhanden sein, also im interrupt und main(oder ist das falsch?)
Das volatile brauchst Du nur bei Variablen, die sowohl in main als auch
im Interrupt verwendet werden. Vermutlich ist das nur bei zahl der Fall.
bit und bit_z brauchst Du dagegen nur im Interrupt, nicht in main.
> Das Rechtecksignal kommt so an:> 01100000 (Im Rechtecksignal)
Also kommt zuerst eine Null, dann zwei Mal eine Eins und dann fünf
Nullen? Und das empfangene Bit steht (als einziges) ganz rechts in der
Variable bit?
Wenn ja, dann sollte mit diesem Code
1
zahl|=(bit<<bit_z);
2
bit_z++;
das rauskommen:
> Müsste also quasi wenn von rechts nach links anfängt in das Byte zu> schreiben so da stehen:> 00000110 also 6.
Wenn etwas anderes rauskommt, lag entweder ein anderes Signal an oder
der Fehler liegt an anderer Stelle im Code. Poste ihn am besten mal
komplett.
> Was ist ein Barrel-shifter??
Ein Barrel-Shifter kann einen Wert mit einem Maschinenbefehl um eine
beliebige Anzahl an Bits verschieben. Auf dem AVR geht das zum Beispiel
nicht, er kann eine Variable mit einem Befehl nur um eine Stelle
verschieben. Bei einer variablen Anzahl an Stellen, wie in dieser
Anweisung
1
zahl|=(bit<<bit_z);
wird der Compiler daraus eine Schleife machen, die bit_z mal läuft und
bit immer eine Stelle weiter nach links schiebt. Erst danach kann der
Wert mit zahl verodert werden. Bei meiner Alternative kann das
Nach-Links-Schieben dagegen jedes Mal mit nur einem Maschinenbefehl
geschehen.
@Em Gr:
Ich hätte auch eine kleine Verständnisfrage:
Was gibt Dir den Takt vor, wann im Programm geschoben werden soll?
Wenn Du die linken Ziffern des Beispiels (01100000) von rechts in den
Akku schiebst, dann erhälst Du natürlich dezimal 96. Schieb die bits von
links auch von links in den Akku und Du erhälst dezimal 6.
Guten Morgen,
spontan:
Also das Rechtecksignal kommt in der Reihenfolge von links nach rechts
gelesen an:
01100000 also Dezimal 6.
Also wird dies doch auch im Code so verarbeitet. Erst wird die 0
erkannt, dann die zwei 1en usw.. Okay, wenn ich dies jetzt von rechts
nach links über
1
zahl|=(bit<<bit_z);
in das byte "zahl" schreibe, dann müsste ja dabei 00000110 rauskommen.
Er fängt ja mit 0 Verschiebungen an, und geht dann weiter bis auf 8 und
fängt dann wieder bei 0 an.
Das beschriebene Byte "zahl", wird das dann von links nach rechts
gelesen, also erstes Bit 1 zweites 2 drittes 4,.. oder von rechts nach
links. Weil dann würde es für mich auch Sinn ergeben, dass er immer 96
anzeigt.
Sorry, bin gerade ein wenig durcheinander von den ganzen bits.
Fabian O., hier ist der Code:
Nochmal eine kleine Frage,
Ich habe gerade am Osca gesehen, das er zwischendurch anscheinende
nochmal einen Interrupt ausslöst.
Wenn ich einen einfach Code, Ausgang = Eingang habe, wird alles ganz
normal erkannt und nochmal genauso ausgegeben.
Wenn ich das ganze per Interrupt mache hat er zwar das ähnliche Signal,
jedoch sind zwischendurch diese "Mini Interrupts", wo ich nicht weiss,
woher die kommen!?
Bits sind in bigendian abgelegt. Das niderwertigste Bit (0) steht also
an höherer Stelle im Speicher. Werte die mehr als ein Byte benötigen
sind jedoch in littleendian abgelegt, d.h. das niederwertigste Byte
steht auch an niederer Stelle im Speicher.
Hier ein Artikel dazu:
http://avr.myluna.de/doku.php?id=de:byteorder
wire