Ich habe hier ein Programm geschrieben wo ich einfach nur einen Pin in
Regelmäßigen Abständen schalten will.
Irgendwie gibt mir AVR-Studio immer StackOverflow.
Ich rufe das Programm auf ...
Beim Timer2CompareMatch Interrupt springt er in das Unterprogramm,
löscht die Sprungadresse welche durch den Interrupt erstellt wurde.
Dann Springt er zum durch den Z Pointer gezeigten Unterprogramm.
Da macht er n bissle was, verändert den Z-Pointer und springt zu next.
Hier wird die durch den ijmp erstellte Adresse aus dem Stack gelöscht
und er springt wieder in die Warteschleife.
Bereits beim zweiten Timer Interrupt bekomme ich einen Stack Overflow.
Stefan Ernst schrieb:> Tobi schrieb:>> Hier wird die durch den ijmp erstellte Adresse aus dem Stack gelöscht>> ???> Ein ijmp erzeugt keine Adresse auf dem Stack.
Verdammt.
Danke, war der Meinung (festen Meinung) das auch ein ijmp einen Eintrag
erstellt.
Wird sicher nicht nochmal vorkommen
Warum kanns das nicht sein?
Lösche die durch den Interrupt erstellte Adresse im Stack
Springe zu dem durch den Z-Pointer angegebenen Programm
Wie würdest du das lösen?
Ein Hardware Interrupt muss wie ein Hardware Interrupt behandelt werden.
Dazu erst mal das Manual konsultieren. Ueblicherweise solte man die
Bedingung loesen, zB den Counter auslesen, dann wird so das betreffende
Interrupt flag geloescht, am Ende kommt dann noch ein iret. Ein jump an
die gleiche Stelle ist nicht dasselbe.
>Der Springt immer an andere Stellen
P1:
ldi Temp, 0x03
out DDRC, Temp
out PORTC, Temp
ldi ZL, LOW(P2)
Wo sorgst du dafür das der Interrupt nicht genau hier ausgelöst wird?
ldi ZH, HIGH(P2)
rjmp Next
Damit das der Interrupt 320 Takte braucht bis er wieder auslöst und dort
die 320 Takte nochnicht erreicht sind.
Ausserdem wird er erst direkt vor dem Rücksprung wieder aktiviert:
Hi
Hör mit diesem Stackgefummel auf. Das es nur etwas für Leute, die sich
100%-tig damit auskennen. Und gerade die vermeiden so etwas. Nur
Anfänger denken das wäre elegant oder notwendig.
In deinem Fall reicht es im Interrupt ein Flag zu setzen, das im
Hauptprogramm ausgewertet wird.
MfG Spess
Tobi schrieb:> Warum kanns das nicht sein?>> Lösche die durch den Interrupt erstellte Adresse im Stack> Springe zu dem durch den Z-Pointer angegebenen Programm>>> Wie würdest du das lösen?
Gar nicht.
Ich würde nach den Regeln spielen.
Ein Interrupt wurde ausgelöst, als Folge davon eine ISR aufgerufen also
hat diese ISR auch wieder mit einem reti zurückzukehren.
Das bringt den Stack nicht in eine Bredullie und sorgt auch bei dem
Interrupteten Code für kein Bauchweh, weil der sich dann auch ein paar
Dinge auf den Stack pushen und poppen kann, OHNE dass Gefahr droht, dass
der Stack überläuft.
Wie gesagt: Spiele nach den Regeln. Meist lebt es sich damit viel
besser.
Hab grad n bissle Überlegt...
Son Register was bei jedem Interrupt hochgezählt wird und wo dann auf
eine Sprungtabelle hingelinkt wird +Zähler = Sprung zu Routine?
Muss ich morgen mal schauen wie das funktioniert
übrigens: ursprüngliches Programm läuft, nun bin ich grad dabei es etwas
einfacher zu schreiben bis es am besten nurnoch ein rcall ist und alles
im Hintergrund abläuft
Dekad Oschi schrieb:> Was soll das Ganze ueberhaupt ? Ich arbeit nun schon seit Jahren mit den> AVR, teilweise auch mit ASM, und hatte noch nie das Beduerftnis fuer> sowas.
Ich hab sowas auch noch nie gebraucht.
Wenn man mit Interrupts arbeitet, sollte ein Int.-Prog. immer so
aussehen:
1
ORG $000
2
rjmp Reset
3
ORG $xxx
4
rjmp Interrupt
5
6
Reset:
7
;Stack init
8
rcall init_Interrupt
9
rcall init_IOs
10
11
;Sonstiges machen und Initialisieren
12
13
loop:
14
;Irgendwelche Flags checken und dann reagieren
15
rjmp loop
16
17
18
Interrupt:
19
push r16
20
;Mach was...
21
pop r16
22
reti
23
;Ab hier wird der Interrupt verlassen, und danach das I-Flag gesezt!
So machs ich seit einiger Zeit; Um die Interrupts möglichst kurz zu
halten lager ich noch ein paar sachen in die Endlosschleife aus.
Der Vorteil daran ist, dass man eben nicht ständig ein Flag checken
muss,
und dadurch mehr Zeit für anderes hat. Also lass es, solange du nicht
auf Platz und Zeit im ns-Bereich achten musst.
julian
spess53 schrieb:> Hi>>>alles im Hintergrund abläuft>> Auf einem AVR läuft nichts im Hintergrund.>> MfG Spess
Ja .. im Hintergrund ist falsch beschrieben.
Sagen wir, das ich nurnoch ein Unterprogramm aufrufen muss welches mir
ein Flag setzt sobald es fertig ist und wo in der Wartezeit immer das
Hauptprogramm frisch fröhlich weiterläuft.