Forum: Mikrocontroller und Digitale Elektronik 'Bit' aus SRAM an bestimmte Stelle im Register


von Michael (Gast)


Lesenswert?

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

von H.Joachim S. (crazyhorse)


Lesenswert?

Der einfachste Weg wird wohl der übers T-Flag sein.

-abhängig von deinem SRAM-bit SET oder CLT
-danach BLD

von Theor (Gast)


Lesenswert?

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.

von Michael (Gast)


Lesenswert?

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

von H.Joachim S. (crazyhorse)


Lesenswert?

Michael schrieb:
> ldi r17, (1 << r16)

Autsch. Lass dir das noch mal durch den Kopf gehen :-)

von Michael (Gast)


Lesenswert?

Darum geht's ja genau
Wie kann ich sowas schreiben, sodass es geht ?

von Axel S. (a-za-z0-9)


Lesenswert?

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.

von Theor (Gast)


Lesenswert?

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.

von Michael (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Pseudocode:
for (loop=0;loop<8;loop++)
   {ld  rx, z+
    ror rx      //Bit 0 ins carry bit
    rol ry      //carry bit ins zielregister
    }

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


Lesenswert?

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'.

von Huh (Gast)


Lesenswert?

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".

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von Axel S. (a-za-z0-9)


Lesenswert?

Helfersyndrom mal wieder. Dem TE wäre langfristig besser gedient, wenn 
er das selber gelernt hätte.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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
Noch kein Account? Hier anmelden.