gred schrieb:
> Ich selber bin auch noch nicht so fit mit asm...
...und auch niht mit dem Lesen von Datenblättern, hättest du ergänzend
anmerken sollen.
Es ist nämlich so: Dein Programm enthält neben mindestens einem
logischen Fehler auch einige Fehler, die aus falscher Benutzung der
Hardware resultieren.
Das wird schon in der Initialisierungssequenz sichtbar, z.B.:
; set direction (0011 1110)
ldi r16, 0x3E
Schon das simple Durchzählen der gesetzten Bits in der Konstanten und
der Vergleich mit der Zahl der LEDs zeigt sofort, dass hier etwas nicht
stimmen kann. Allerdings: der Fehler ist bezüglich der Funktion
irrelevant, da der Port-Override für den Reset-Pin wohl aktiv ist und
somit zumindest nichts Schädliches passiert.
Es wäre allerdings denkbar, dass du geplant hast, später auch an den
Reset-Pin eine LED zu hängen, dann wäre die Initialisierung korrekt,
aber dann hättest du das zumindest als Kommentar vermerken sollen.
; disable unneeded ADC
ldi r16, 0x80 ; = 1000 0000
out ADCSRA, r16
Das ist falsch, das schaltet den ADC EIN, nicht aus. Du kannst die
Ausgabe komplett weglassen, denn der ADC ist nach einem Reset sowieso
disabled.
; enable timer0, every 1ms
ldi r16, 0x03 ; prescaler = 64
out TCCR0B, r16
Das ist nicht gut. Das startet bereits den Timer und zwar bevor du ihn
vollständig initialisiert hast. Durchaus möglich, dass das im konkreten
Fall kein Problem darstellt, aber du solltest dir generell angewöhnen,
den Zugriff auf TCCRnB immer als letztes auszuführen, denn es gibt
reichlich Konfigurationen, bei denen das durchaus relevant sein kann.
.macro POWERDOWN
ldi r20, 0x30 ; set powerdown mode (0011 0000)
out MCUCR, r20
sleep
nop
.endmacro
Wenn du Macro den Schlafmodus erlaubst, solltest du ihn hier auch wieder
verbieten. Ersetze das (sowieso sinnlose) nop durch:
clr R20
out MCUCR, r20
Dasselbe gilt analog für dein anderes Schlafmacro.
Überhaupt ist die Verwendung der beiden Macros etwas zweifelhaft. Du
verwendest sie nur an jeweils genau einer Stelle im Programm, in solch
einem Fall sind Macros kontraproduktiv, sie erschweren dann nur das
Debuggen im Simulator und erleichtern genau garnix.
Gerade für Anfänger ist es sehr viel einfacher, Unterprogramme statt
Macros zu verwenden, zumal in einer solchen Anwendung, in der Rechenzeit
keine Rolle spielt.
timer0_compare:
adiw time_l, 1
reti
Das verändert die Flags! Du musst sie zu Beginn der ISR retten und am
Ende wiederherstellen, sonst passiert im Hauptprogramm typischerweise
Müll.
Soviel zur Hardwarenutzung, nun noch der logische Fehler im Programm,
der mir sofort aufgefallen ist:
dec r17
DOSLEEP 800
brne Loop2
Das "brne Loop2" macht hier nicht das, was du glaubst, was es täte. Und
wenn du nicht unsinnigerweise das Macro verwendet hättest, wäre dir auch
schnell klar, warum das so ist. Schreibe also den Inhalt des Macros
(natürlich entsprechend angepaßt) direkt an die Stelle des
Macro-Aufrufs, steppe die Sache im Simulator durch und beobachte das
Zeroflag...