Hi zusammen, Ich habe den Aufbau wie im Anhang zu sehen. Nun will ich eigentlich nur das die LEDs mehrmals nach einander (quasi wie eine Animation) angeschaltet werden. Nur werden alle LEDS auf einmal eingeschaltet nach dem Einschalten des AVRs. Hat jemand eine Idee? Ich selber bin auch noch nicht so fit mit asm... Gruß G.
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...
VIELEN DANK! Du hast mir wirklich geholfen, das waren einige echt blöde Fehler. Zusätzlich auch noch der hier:
1 | ldi r16, 2 ; Compare A match Interrupt |
2 | out OCIE0A, r16 |
statt
1 | ldi r16, (1<<OCIE0A) ; Compare A match Interrupt |
2 | out TIMSK0, r16 |
Hab erst mal nur die groben Schnitzer korrigiert, jetzt läuft es :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
