Ich hab mir schon einiges überlegt, aber finde irgendwie nicht so recht eine Lösung, wie ich ein Byte das im SRAM des Attiny steht (Inhalt entweder 0 oder 1)an ein bestimmte Stelle im Register schreiben kann. Hat da wer eine Idee Viele Grüße Michael Btw. Ich verwende Assembler
Der einfachste Weg wird wohl der übers T-Flag sein. -abhängig von deinem SRAM-bit SET oder CLT -danach BLD
Solche Problemstellungen gehören zu den häufig Auftretenden. Ihr Lösung besteht in der Anwendung von sogenannten "Bitmanipulationen". Grob gesagt, ist der Ablauf etwa wie folgt: 1. Isolierung des Wertes eines einzelnen Bits. Dabei ist der Transport von zunächst allen Bits in ein Register, auf das man Befehle zur Bitmanipulation anwenden kann, wiederum eine triviale Aufgabe. Wesentlich ist die Anwendung einer "Bitmaske" in der Verknüpfung des veränderlichen Bits und mit einer "Und"-Operation um den Wert des Bytes nur noch von dem fraglichen einzelnen Bit abhängen zu lassen. 2. Das Verschieben des veränderlichen Bits von einer Position im Byte zu einer anderen. Dazu werden Bit-Schiebeoperationen verwendet. Ihre Anwendung, - das ist aber hier nicht wesentlich -, verändert auch den Wert des Bytes, wenn es etwa als Integer-Zahl interpretiert wird. Einzelheiten findest Du in dem Artikel: https://www.mikrocontroller.net/articles/Bitmanipulation hier im Forum. Da es sich um ein Basisthema handelt, finden sich im Internet dazu reichlich alternative Darstellungen.
Ist so eine Möglichkeit denkbar?
1 | ldi r16, 7 |
2 | ldi r17, (1 << r16) |
Ich möchte möglichst wenig aufwand haben dehalb wollte ich versuchen mit einem Zähler in einem Register (r16) die einzelenen Bits durchzuegehn? Kann den Code oben jetzt grade nicht ausprobieren Viele Grüße Michael
Darum geht's ja genau Wie kann ich sowas schreiben, sodass es geht ?
Michael schrieb: > Ist so eine Möglichkeit denkbar? > >
1 | > ldi r16, 7 |
2 | > ldi r17, (1 << r16) |
3 | > |
Warum probierst du es nicht einfach aus und liest die Fehlermeldung? Alternativ lies die Beschreibung des AVR Befehlssatzes. > Ich möchte möglichst wenig aufwand haben dehalb wollte ich versuchen mit > einem Zähler in einem Register (r16) die einzelenen Bits durchzuegehn? Warum willst du jetzt alle Bits durchgehen? Erst hieß es noch, du wolltest nur ein einzelnes Bit eines Bytes aus dem RAM testen. Wenn du beim Schreiben des Programms schon weißt, welches Bit du testen mußt, dann kannst du die Bitmaske als Konstante direkt in das Programm schreiben. Wenn du hingegen alle Bits testen willst, dann kannst du entweder mit einer Maske auf Bit 0 anfangen (auch wieder eine Konstante) und dann die Maske mit Schiebebefehlen durch dein Register schieben. Eleganter ist es jedoch, das zu testende Byte selber durch das Carry-Flag zu schieben. Dann kriegst du die Bits der Reihe nach in das Flag und kannst mit Branch- oder Skip-Befehlen die gewünschten Aktionen abhängig vom Wert des Bits ausführen.
Michael schrieb: > ldi r17, (1 << r16) Nein. Das geht nicht so. Der Text eines Assemblerprogrammes unterliegt, wie der eines C-Programmes einer bestimmten "Deutung"; er hat eine Bedeutung, eine genau fest gelegte Interpretation. Diese ist in dem Assembler-Manual des Assemblers beschrieben. Im AVR-Studio (ich vermute mal einen AVR), unter "Hilfe" beschrieben. Dein Fehler hier, besteht darin, dass Du einen konstanten Ausdruck hinschreiben willst, aber darin ein Register verwendest. Konstante Ausdrücke sind aber das, was der Assembler laut seiner Beschreibung und das wiederum, laut der Beschreibung des Befehles "LDI" (Load Immediate) als rechten Operanden erwartet. "Immediate" ist in diesem Kontext ein anderes Wort für "Konstante". Nun ist es aber so, dass konstante Ausdrücke zu dem Zeitpunkt berechnet werden, in dem der Assembler (das Programm, dass "Assembler" heisst und ein in der Assembler-Sprache geschriebenes Programm interpretiert) aus diesem Programm eine von dem Prozessor verstandene Darstellung macht; das nennt man assemblieren. Daraus folgt, dass Du in konstanten Ausdrücken nichts verwenden darfst, was nicht schon zu diesem Zeitpunkt bekannt ist. Insbesondere nicht den Inhalt von Registern, denn deren Inhalt, wird erst zu der Zeit bestimmt, zu der das Programm vom Prozessor ausgeführt wird. (Das ist in gewisser Weise eine vereinfachte, formal nicht korrekte Darstellung, aber sie stimmt im wesentlichen). Daraus folgt, dass Du als "Immediate", als "Konstante" zwar etwa (1 << 7) genau wie: (5 * 4) + 8 oder ähnliches schreiben kannst, aber nicht das von Dir gezeigte. Faustregel kann etwa folgendes sein: Alles was Du selbst (auf dem Papier oder im Kopf) ausrechnen kannst, so das eine bestimmte Zahl herauskommt, ohne das Du den tatsächlichen Inhalt eines Registers oder einer Speicherstelle kennen musst, darfst Du dort hinschreiben.
Also damit das auch jeder versteht wie ich es meine. Ich hab im SRAM 8 Byte gespeichert die entweder den Wert 0 oder 1 haben. Über den Z-Pointer greif ich auf das erste Byte im Ram zu. Jetzt will ich das ganze in ein Register zusammen schreiben. (Geht ja weil die Bytes immer nur den Wert 0 oder 1 haben) 0 Byte aus dem Ram an die 7te Stelle im Register 1 Byte aus dem Ram an die 6te Stelle im Register . . . 7 Byte aus dem Ram an die 0te Stelle im Register Ich hoffe ich bin verständlich genug Wenn also irgendwer n Plan hat wäre ich demjenigen sehr verbunden mir das mitzuteilen. Michael
Dann schau Dir mal die Rotierbefehle über Carry an, die sind genau dafür gemacht. Am einfachsten wäre es aber, die Bits gleich beim Schreiben in den SRAM zu packen.
Pseudocode: for (loop=0;loop<8;loop++) {ld rx, z+ ror rx //Bit 0 ins carry bit rol ry //carry bit ins zielregister }
Michael schrieb: > Ich hab im SRAM 8 Byte gespeichert die entweder den Wert 0 oder 1 haben. Woher kommen diese 8 Bytes? Ist das jeweils eine binäre 1 und eine binäre 0? Oder eine ASCII-'1' und eine ASCII '0'.
Lothar M. schrieb: > Michael schrieb: >> Ich hab im SRAM 8 Byte gespeichert die entweder den Wert 0 oder 1 haben. > Woher kommen diese 8 Bytes? > Ist das jeweils eine binäre 1 und eine binäre 0? > Oder eine ASCII-'1' und eine ASCII '0'. Ich glaube eher, Michael kennt nicht den Unterschied zwischen "Bit" und "Byte". Seine ganze Umschreibung deutet darauf hin, daß er "Bit" meint".
Michael schrieb: > Jetzt will ich das ganze in ein Register zusammen schreiben. (Geht ja > weil die Bytes immer nur den Wert 0 oder 1 haben) > > 0 Byte aus dem Ram an die 7te Stelle im Register > 1 Byte aus dem Ram an die 6te Stelle im Register > . > Wenn also irgendwer n Plan hat wäre ich demjenigen sehr verbunden mir > das mitzuteilen. Ja.
1 | .DSEG |
2 | Arr: .byte 8 |
3 | |
4 | .CSEG |
5 | ldi zl, low(Arr) |
6 | ldi zh, High(Arr) |
7 | ldi r16, 8 |
8 | lp2: ld r17, Z+ |
9 | lsr r17 |
10 | rol r19 ;* Wenn Arr[0] => bit7 |
11 | dec r16 |
12 | brne lp2 |
13 | |
14 | end: rjmp end |
Resultat in R19.
Michael schrieb: > Wenn also irgendwer n Plan hat wäre ich demjenigen sehr verbunden mir > das mitzuteilen. Und wenn die Werte nicht nur 0 und 1 sind:
1 | .DSEG |
2 | Arr: .byte 8 |
3 | |
4 | .CSEG |
5 | ldi zl, low(Arr) |
6 | ldi zh, High(Arr) |
7 | clr r19 |
8 | ldi r18, 0x80 |
9 | ldi r16, 8 |
10 | lp2: |
11 | ld r17, Z+ |
12 | tst r17 |
13 | breq next |
14 | or r19, r18 |
15 | next: |
16 | lsr r18 |
17 | dec r16 |
18 | brne lp2 |
19 | |
20 | end: |
21 | rjmp end |
Resultat wieder in R19.
Helfersyndrom mal wieder. Dem TE wäre langfristig besser gedient, wenn er das selber gelernt hätte.
Axel S. schrieb: > Helfersyndrom mal wieder. Das ist doch der tiefere Sinn eines Forums, oder ? > Dem TE wäre langfristig besser gedient, wenn > er das selber gelernt hätte. Wie schon die alten Griechen behaupteten: Ein Codeschnipsel sagt mehr als Tausend Worte
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.