Hallo,
ich habe 2 (Verständnis-)Probleme:
Den unten angegebenen Code simuliere ich im AVRStudio, dabei fällt mir
folgendes auf:
1. Der erste Interrupt wird direkt nach Aktivierung der Interrupts (sei)
ausgelöst, wenn ich nicht den auskommentierten Teil einfüge:
1
;ldi temp, 0b00010000
2
;out TIFR, temp
Aber der Zähler hat laut Simulation noch gar nicht den vorgegebenen Wert
erreicht? Wieso gibt es dann bereits einen Interrupt?
2. Damit zusammen hängt auch meine zweite Beobachtung: OC1A wird nach
Setzen des Highregisters von OCR1A getoggelt, genauso nach Setzen des
Lowteils. Eigentlich hätte ich erwartet, dass OC1A erst nach Auftreten
des Interrupts getoggelt wird. Wo ist mein Denkfehler?
Das Programm soll eigentlich mehrere Rechteckimpulse nacheinander
ausgeben, deren Länge durch Festsetzen des CTC-Wertes vorgegeben wird.
Die Schleife wird also für weitere Rechteckimpulse (deren Länge jedes
Mal anders ist, daher ist wahrscheinlich PWM nicht so günstig) noch
erweitert.
Da die einzelnen Impulse im Mikrosekundenbereich liegen, arbeite ich mit
Assembler, da die Zeit dann doch ein kritisches Problem ist.
Erstens hat das nichts mit GCC zu tun. Falsches Forum.
Zweitens ist Deine Vektortabelle völlig falsch. Der Mega16 hat mehr als
8 KiB Flash und demzufolge sind die Interrupt-Vektoren 32 Bit breit.
reti und rjmp sind aber nur 16 Bit breit. Nimm doch einfach die
Vektortabelle, die im Datenblatt steht. Die stimmt nämlich.
Alex Th. wrote:
> 1. Der erste Interrupt wird direkt nach Aktivierung der Interrupts (sei)> ausgelöst, wenn ich nicht den auskommentierten Teil einfüge:>>
1
;ldi temp, 0b00010000
2
> ;out TIFR, temp
3
>
> Aber der Zähler hat laut Simulation noch gar nicht den vorgegebenen Wert> erreicht? Wieso gibt es dann bereits einen Interrupt?
Doch, hat er. In dem Moment, wenn Du den Timer startest und im OCR noch
0 steht, ist der Compare-Wert bereits erreicht und dementsprechend wird
beim nächsten Takt das Flag gesetzt (Prescaler ist ja 1). Wenn Dir das
händische Löschen des Flags Unannehmlichkeiten bereitet, dann solltest
Du den Timer erst dann starten, wenn alle Initialisierungen gemacht sind
(also wenn im OCR ein sinnvoller Wert steht)...
Hi Johannes,
mit dem gcc habe ich mir fast gedacht, aber nicht besser gewusst. In
welches Unterforum gehört eine solche Frage denn eigentlich? Bei µC und
Elektronik wird ja mehr der Hardwarebereich besprochen, zumindest nach
den Topics, die ich dort gesehen habe.
Die Interrupttabelle habe ich erst vom ATMega8 übernommen, als das nicht
passte, habe ich mir den richtigen Interrupt per Breakpoint bei
AVRStudio rausgesucht. Das mit dem Datenblatt hätte mir selber einfallen
können, weil ich da heute den gesamten Tag nach dem Fehler gesucht habe.
;)
Nun aber zum eigentlichen: Danke! Das war es tatsächlich, so ist
natürlich auch das Toggeln des OC1A zu erklären. Hab den Code jetzt
umgestellt. Vielen Dank noch mal.
Schönen Gruß,
Alex