Ausgänge werden falsch geschaltet (asm, tiny13)

Gast #4394661
Lesenswert?
• ▲
▼
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.
Angehängte Dateien:
Gast #4394681
Lesenswert?
• ▲
▼
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...
Gast #4395774
Lesenswert?
• ▲
▼
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 :)
Angehängte Dateien:

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.