Forum: Mikrocontroller und Digitale Elektronik Port variabel setzen/löschen


von Manfred Richter (Gast)


Lesenswert?

Hi,

ich suche nach einer Lösung um in AVR-Assembler folgendes zu machen:

ldi r16,5         ;kann zwischen 0 und 7 sein (Port bit)
...
sbi PORTB,r16

Mir ist schon klar, dass ich so etwas machen könnte:

ldi r16,5         ;kann zwischen 0 und 7 sein (Port bit)
...

cpi r16,5
brne weiter
sbi PORTB,5

weiter:
cpi r16,6
brne weiter1
sbi PORTB,6

weiter1:
....

Irgendwie sieht das aber nicht so elegant aus und braucht auch einiges
an Speicher wenn ich da 14 ports setzen oder löschen will.

Hat jemand eine Idee, wie man das eleganter lösen könnte?

Danke,
Manfred

von johnny.m (Gast)


Lesenswert?

"sbi PORTB, r16" dürfte eine Fehlermeldung geben. Der zweite Operand
von sbi muss eine Zahl zwischen 0 und 7 sein und kein Register!

von johnny.m (Gast)


Lesenswert?

Ah, jetzt verstehe ich... Du suchst nen Ersatz dafür...

Mach es z.B. mit

ldi r16, 5
in r17, PORTB
or r17, r16     ; logische ODER-Verknüpfung, setzt Bitmaske
out PORTB, r17

So in der Art, oder hab ichs immer noch falsch verstanden?

von johnny.m (Gast)


Lesenswert?

...und zum Löschen:

ldi r16, 5
com r16      ; r16 invertieren
in r17, PORTB
and r17, r16 ; logisches UND mit der invertierten Bitmaske
out PORTB, r17

von Andreas H. (asmhesse)


Lesenswert?

Hallo,

ich glaube Manfred will ein einzelnes Bit setzen. Das zu setzende Bit
steht in einer Variablen.

  ldi r16,0
  ldi r17,5
  sec
Schleife:
  rol r16
  dec r17
  brne Schleife
  in  r17, PORTB
  or  r17. r16
  out PORTB, r17

Gruss
Andreas

von johnny.m (Gast)


Lesenswert?

Andreas hat recht. Hatte das nicht richtig gesehen, dass Du nur die
Nummer des Bits angeben willst. Da ist seine Methode das Sinnvollste.
Es muss nur in der vorletzten Zeile "or r17, r16" heißen...

von Manfred Richter (Gast)


Lesenswert?

Hallo Zusammen,

vielen Dank für die schnelle Hilfe - genau das war es was ich suchte
:)))

Grüsse,
Manfred

von johnny.m (Gast)


Lesenswert?

Hab noch ein Problem bei Andreas' Lösung gefunden: Die Bit-Nummer in
r17 muss vor der Schleife noch um eins erhöht werden. Wenn Bit Nr. 0
gesetzt werden soll (also in der zweiten Zeile "ldi r17, 0" steht),
dann gehts schief, weil dann das brne nicht greift ("dec r17" gibt in
dem Fall einen Überlauf). Die Schleife wird also nicht verlassen.
Außerdem wird die Schleife immer einmal zu wenig durchlaufen.

Das Problem ließe sich lösen, indem man vor dem "sec" ein "inc r17"
einfügt. Dann wird auch mit dem Aufruf "ldi r17, 5" das Bit Nr. 5
(also das sechste von hinten) gesetzt.

Löschen geht dann so, wie ich es oben beschrieben habe, indem anstelle
von
  in  r17, PORTB
  or  r17. r16
  out PORTB, r17
folgendes eingesetzt wird:
  in r17, PORTB
  com r16
  and r17, r16
  out PORTB, r17

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.