Forum: Mikrocontroller und Digitale Elektronik Ausgänge werden falsch geschaltet (asm, tiny13)


von gred (Gast)


Angehängte Dateien:

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.

von c-hater (Gast)


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...

von gred (Gast)


Angehängte Dateien:

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 :)

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.