Forum: Mikrocontroller und Digitale Elektronik [avrsm] variables Bit manipulieren


von Fabian S. (fabian727)


Lesenswert?

Hi @all,

Ich versuche ein Lauflicht in Assemblersprache im Attiny2313 zu 
animieren.
Es sollen immer 3 LEDS gleichzeitig aktiv sein.
Die vorderste (1. LED) soll heller werden.
Die mittlere  (2. LED) soll einfach leuchten.
Die hinterste (3. LED) soll dunkler werden.

sobald 1. und 3. LED ihr Ziel erreicht haben, soll dieses
Muster sich um 1 nach vorne verschieben und das ganze wieder passieren.
Der Einfachheit halber, werden nur insgesamt 8 LEDS angesteuert -> 1 
Register.

Ich habe bereits eine Schleife geschrieben, die die LEDS durchs Register 
schiebt.
Ich habe ebenfalls bereits eine Schleife geschrieben, in der 1 
festgelegte LED heller wird. -> dunkler wird somit auch kein Problem 
sein.

Mein Problem liegt daran, dass ich nicht weiß, wie ich das Verschieben 
realisieren soll. D.h. bit 0 bis 2 werden angesteuert. Jetzt wirds 
verschoben, aber wie erkläre ich dem Teil der software, der die LEDS 
heller / dunkler macht, dass er jetzt ein Bit weiter links das machen 
soll?

Ich hoffe ich konnte mich verständlich ausdrücken, sonst bitte nochmal 
nachfragen

von Hmm (Gast)


Lesenswert?

Nochmal nachfrag.

von Spess53 (Gast)


Lesenswert?

Hi

Welcher Controller?

Mfg Spess

von Hmm (Gast)


Lesenswert?

Attiny2313

von Fabian S. (fabian727)


Lesenswert?

welchen Teil nicht kapiert?

Ich will 3 LEDS gleichzeitig ansteuern. Die 1. davon geht an, die 2. 
leuchtet dauerhaft, die 3. LED geht aus. Dieses Muster, sobalds beendet 
ist (also 1. LED leuchtet, 3. LED ist aus) wird verschoben und wieder 
von vorne angefangen.

Gibt quasi ein Lauflicht, das nicht "hart" umläuft, sondern die erste 
LED eben angeht und die letzte immer aus.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Fabian S. schrieb:
> Mein Problem liegt daran, dass ich nicht weiß, wie ich das Verschieben
> realisieren soll. D.h. bit 0 bis 2 werden angesteuert. Jetzt wirds
> verschoben, aber wie erkläre ich dem Teil der software, der die LEDS
> heller / dunkler macht, dass er jetzt ein Bit weiter links das machen
> soll?

Hallo Fabian, ich weiß auch nicht genau, ob ich dich richtig verstanden 
habe.

Wahrscheinlich brauchst du parallel drei Register, die rotiert werden 
müssen:

r1 für die LED, die dunkel wird, Startwert 0b00000001
r2 für die LED, die leuchtet, Startwert 0b00000010
r3 für die LED, die heller wird, Startwert 0b00000100

Die Hellerwerden-Prozedur verwendet dann z.B. das Register r3 zum 
Maskieren des hellerzuschaltenden Pins im Port.

Alle drei Register werden taktweise nach links rotiert.

von Bernie (Gast)


Lesenswert?

Nehmen wir mal an, du das hast das heller/dunkler werden
schon zum Laufen bekommen:

- Mit Hardware-PWM?
  Das geht nur an den dafür geeigneten Port-Pins,
  lässt sich also nicht einfach an 8 aufeinander folgende
  Port-Pins verschieben.

- Mit Software-PWM?
  Dann ist es machbar, allerdings etwas aufwändiger.

Wie hast du denn dem µC gesagt, dass er genau eine LED zum
heller/dunkler werden ansteuert?

Wo ist das Problem, dies an einem anderen PortPin zu machen?

von Karl H. (kbuchegg)


Lesenswert?

Fabian S. schrieb:
> welchen Teil nicht kapiert?

Kapiert schon.
Aber das wird aufwändig, da ein allgemein verwendbares Schema zu finden.

von Fabian S. (fabian727)


Lesenswert?

im moment kann ich 1 LED an einem Ausgang, heller oder dunkler machen.
Ich glaube nicht, dass es schwer ist dieses in ein Register zu 
übertragen.
Aber nun habe ich in 1 Register stehen, ob diese LED leuchten soll oder 
nicht. Angenommen im 1. Bit von temp und ich habe deine 3 Register zum 
Cluster ausgeben, wie schaffe ich es nun, mein 1. Bit von temp in das 
entsprechende Bit des Clusterregisters zu geben? Da dieses Bit sich ja 
immer wieder ändert.
Hier kommt eben mein Problem ins Spiel, ich will ein Bit, das sich 
ändert, ansteuern / verändern.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Fabian S. schrieb:
> im moment kann ich 1 LED an einem Ausgang, heller oder dunkler machen.
> Ich glaube nicht, dass es schwer ist dieses in ein Register zu
> übertragen.
> Aber nun habe ich in 1 Register stehen, ob diese LED leuchten soll oder
> nicht. Angenommen im 1. Bit von temp und ich habe deine 3 Register zum
> Cluster ausgeben, wie schaffe ich es nun, mein 1. Bit von temp in das
> entsprechende Bit des Clusterregisters zu geben? Da dieses Bit sich ja
> immer wieder ändert.
> Hier kommt eben mein Problem ins Spiel, ich will ein Bit, das sich
> ändert, ansteuern / verändern.

Ich glaube, das Problem liegt in Zeile 42.
Falls du verstehst, was ich damit sagen will... ;-)

Es würde helfen, wenn du uns den Code-Ausschnitt zeigst...

von Karl H. (kbuchegg)


Lesenswert?

Fabian S. schrieb:
> im moment kann ich 1 LED an einem Ausgang, heller oder dunkler machen.
> Ich glaube nicht, dass es schwer ist dieses in ein Register zu
> übertragen.

Die Sache ist die, dass du die LED nicht mehr direkt am Port dimmen 
kannst, sondern du dir ein entsprechendes Byte im Speicher vorbereiten 
musst, welches dann als ganzes auf den Port gegeben wird. Und in diesem 
Byte sind dann genau die Bits gesetzt du zum jeweiligen Zeitpunkt 
benötigt werden.

von Fabian S. (fabian727)


Lesenswert?

und genau hier liegt mein Problem, bei dem ich die Hoffnung hatte, dass 
ihr mir weiter helfen könnt:

Die Sache ist die, dass du die LED nicht mehr direkt am Port dimmen
kannst, sondern du dir ein entsprechendes Byte im Speicher vorbereiten
musst, welches dann als ganzes auf den Port gegeben wird. Und in diesem
Byte sind dann genau die Bits gesetzt du zum jeweiligen Zeitpunkt
benötigt werden.

Wie kann ich sagen, verschiebe nun Bit1 aus Register1 in Bit1 von 
Register2, das nächste mal aber in Bit2 von Register2 und danach in Bit3 
von Register2.

Ich bin im moment am schreiben vom code. Es sind alles nur Fetzen, aus 
einzelnen Programmen. Deswegen kann ich schlecht etwas vorweisen. Sry.

von Karl H. (kbuchegg)


Lesenswert?

Fabian S. schrieb:
> und genau hier liegt mein Problem, bei dem ich die Hoffnung hatte, dass
> ihr mir weiter helfen könnt:

Langsam.
So einfach ist das jetzt auch nicht aus dem Ärmel zu schütteln.


> Wie kann ich sagen, verschiebe nun Bit1 aus Register1 in Bit1 von
> Register2, das nächste mal aber in Bit2 von Register2 und danach in Bit3
> von Register2.

Du bist am falschen Dampfer.
Das muss man ganz anders angehen.
Markus hat da weiter oben schon eine prinzipiell brauchbare rudimentäre 
Idee geliefert. Aber eine Idee ist noch kein Programm.

von Fabian S. (fabian727)


Lesenswert?

ich hatte die Hoffnung, dass es eine Möglichkeit gibt, wie in [c]. Dort 
hab ich gelesen, dass man Variablen für die Bits einsetzen kann und dann 
diese Variable einfach verändert.

Wenn ich am falschen Dampfer bin, wie muss ich dann umdenken, damit ich 
es sinnvoll schreiben kann?

von Karl H. (kbuchegg)


Lesenswert?

Fabian S. schrieb:
> ich hatte die Hoffnung, dass es eine Möglichkeit gibt, wie in [c]. Dort
> hab ich gelesen, dass man Variablen für die Bits einsetzen kann und dann
> diese Variable einfach verändert.
>
> Wenn ich am falschen Dampfer bin, wie muss ich dann umdenken, damit ich
> es sinnvoll schreiben kann?

Die grundsätzliche Idee besteht darin, dass man wie schon gesagt 3 
Register hat, in denen das jeweilige Bit für je eine der LEDs stehen. 
Nennen wir sie mal LED_d, LED_k, LED_h (für dunkler, konstant, heller. 
Also die LED deren Bit in einem dieser Register zb auf 1 ist, ist 
diejenige, welche dunkler, konstant bzw. heller gedimmt werden soll.

Die Idee geht weiter mit:
Aus diesen 3 Registern verodert man sich jetzt 2 Bytes.
Byte 1 besteht aus
   LED_d verodert mit LED_k
Byte 2  besteht aus
   LED_h verodert mit LED_k

diese beiden Bytes werden jetzt im Wechsel ausgegeben. Byte 1 wird n mal 
ausgegeben, Byte 2 wird m mal ausgegeben. Wobei n und m gegengleich 
erhöht bzw. verringert werden. (und n + m eine konstante Zahl, im 
folgenden 11 ergibt).

Die Dimmung beginnt zb damit, dass Byte 1 10 mal ausgegeben wird und 
Byte 2 nur 1 mal. Danach wird Byte 1 9 mal ausgegebn und Byte 2 2 mal. 
Dann Byte 1 8 mal und Byte 2 3 mal. etc. Solange bis man durch ist und 
Byte 1 1 mal ausgegeben wurde und Byte 2 10 mal.

Der Effekt ist jetzt der, dass die 1 im Byte 1, die durch LED_d 
eingebracht wurde zeitmässig immer weniger Anteil bekommt, während die 1 
von LED_h in Byte 2 immer mehr zeitmässigen Anteil bekommt.

(die 10 sind jetzt nur eine Zahl. Je nach Geschwindigkeit wird man das 
natürlich öfter machen)

Ist ein Dimmvorgang durch, dann werden alle 3 Ausgangsregister LED_d, 
LED_k und LED_h um 1 Bit nach links rotiert und das ganze Spiel beginnt 
wieder von vorne
   die beiden Bytes zusammenodern
   und im Wechsel mit laufend veränderten Verhältnissen ausgeben.

von Fabian S. (fabian727)


Lesenswert?

geiler Gedanke. Ok, jetzt muss ich mir Gedanken machen, wie ich das am 
besten programmiere. Auf so einen einfachen Ansatz muss man erst kommen, 
wenn man schon so um Ecken denkt, wie ich
danke erstmal.
Mal schauen, wann weitere Probleme aufkreuzen

von Karl H. (kbuchegg)


Lesenswert?

Fabian S. schrieb:
> geiler Gedanke.

Du hast die Idee verstanden?
Respekt!
Die ist noch so unausgegoren, dass ich sie selbst beim Lesen nicht 
richtig verstehen würde, wenn ich das lese was ich geschrieben habe :-)

Aber im Ernst: Ich denke, so oder zumindest so ähnlich müsste das gehen.

von Fabian S. (fabian727)


Lesenswert?

ich habe meine Idee inzwischen ausgeschrieben. Wenn sie jetzt auch noch 
auf Anhieb fast klappt, dann bin ich stolz :D

Wenn nicht, leg ich sie bei Seite und programmiere deine Idee.
Ja ich habe sie verstanden, glaub ich zumindest. Ich denke öfters um 
viele Ecken, statt den geraden Weg zu nehmen

von Fabian S. (fabian727)


Angehängte Dateien:

Lesenswert?

nochmals vielen Dank für die Hilfe hier im Forum. Ich hoffe sie kommt 
an.
Soweit im Moment ersichtlich ist, dürfte das Projekt jetzt abgeschlossen 
sein
Anbei hängt der code.

von Fabian S. (fabian727)


Angehängte Dateien:

Lesenswert?

oups sieht so aus, als obs die falsche datei gewesen wäre

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.