Forum: Mikrocontroller und Digitale Elektronik Lauflicht (Zeitverzoegerung)


von Daniel Derichs (Gast)


Lesenswert?

Hallo ;)
Ich bin neu und unerfahren im Bereich der AVRs.
Als ersten Versuch wollte ich ein kleines Lauflicht (mit 3 Dioden)
basteln. Ich habe mir also einen Delay mit dem AVR delay loop generator
schreiben lassen. Dieser Codeschnipsel funktioniert soweit auch.
Nun habe ich mir eine Unterfunktion "delay" geschrieben:
-------
delay:
          ldi  R29, $06
WGLOOP9:  ldi  R30, $37
WGLOOP10: ldi  R31, $C9
WGLOOP11: dec  R31
          brne WGLOOP11
          dec  R30
          brne WGLOOP10
          dec  R29
          brne WGLOOP9

          nop
          ldi R29, 0
          ldi R30, 0
          ldi R31, 0
ret
-------
Diese benutze ich wie folgt:
-------
loop:
         ldi r16, 0b11111011
         out PORTB, r16

         rcall delay

         ldi r16, 0b11111101
         out PORTB, r16

         rcall delay
[...]
         rjmp loop
-------
Wenn ich das ganze nun Assembliere und auf den µC schreibe, leuchtet
nur die letzte Diode (konstant).
Ich habe einige Sourcecodes durchgeschaut, was aber nicht zu einer
Loesung meines Problems fuehrte.
Ueber eine Antwort waer ich sehr dankbar ;)

Daniel "trasher" Derichs

von Fiffi (Gast)


Lesenswert?

Hallo Daniel,

leg bitte mal die komplette Datei in den Anhang.

Auf den ersten Blick fehlt oben in deinem Programm, daß du die Pins als
Ausgänge kofigurierts. (Siehe Register DDRB)


Gruß

Fiffi

von Daniel Derichs (Gast)


Lesenswert?

Hi,
der Port wurde wie folgt als Ausgang konfiguriert:
         ldi r16, 0xFF
         out DDRB, r16
Das war dann auch schon der gesamte Code.
Wenn ich das "rcall delay" durch den Delay code ersetze, funktioniert
alles Problemlos.
Da ich diesen Code aber mehrfach verwende, wollte ich das ganze
vereinfachen.

Daniel "trasher" Derichs

von Johannes M. Richter (Gast)


Lesenswert?

Sobald Du ein rcall verwendest, musst Du auch den Stackpointer
initialisieren.

Ich garantiere jetzt nicht fuer Richtigkeit, aber je nach verwendetem
AVR musst Du entweder

ldi temp, LOW(RAMEND)    ; initialize stack pointer
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp

oder

ldi temp, RAMEND
out SP, temp

eingeben. Man korrigiere mich bitte, besonders bei der 2. Variante bin
ich unsicher.

von Johannes M. Richter (Gast)


Lesenswert?

Sorry, schon wieder; zur Klarstellung: temp ist dabei einfach ein
Register.

von Daniel Derichs (Gast)


Lesenswert?

Hab es mit beiden Varianten versucht (temp als r14 definiert).
Beim ldi bekomme ich immer "Illegal argument type or count" (bei
beiden Varianten).

von Daniel Derichs (Gast)


Lesenswert?

Problem geloest.
Lag tatsaechlich am Stackpointer ;)
Letztere Variante tut bei mir (ATmega8) wunderbar.
Habe temp nun als R23 definiert, mit R14 wollte es nicht ;)

Danke,
Daniel "trasher" Derichs

von Quark (Gast)


Lesenswert?

Guten Morgen,

in der Hilfe zum AVR-Studio findet sich auch eine Beschreibung
des ldi -Befehles.

Zitat: "Loads an 8 bit constant directly to register 16 to 31."

Deswegen funzt es mit R14 nicht.

Viel Spaß bei deiner AVR Enseckungstour,

Quark

von Bernhard (Gast)


Lesenswert?

Moin,

wie kann ich dann denn die Register r0 - r15 ansprechen, wenn der ldi
Befehl nur für die oberen Register gültig ist??

Bernhard

von Quark (Gast)


Lesenswert?

Hallo Bernhard

z.B. mit MOV, LD und vielen anderen Befehlen lassen sich
die Register R0-R15 ansprechen.
Sie sind nur nicht zum direkten (Immediate) Laden einer Konstanten
zu gebrauchen.

Grüße

Quark

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.