Moin,
mein Display funktioniert jetzt wunderbar, ich hab aber jetz noch ein
Problem mit den Interrupts, wo ich auch nicht mehr weiter weiss.
Und zwar soll mein Programm (Phasenabschnittsteuerung mit wählbaren Ein-
und Auschaltwinkel) bei jedem Nulldurchgang einen Interrupt starten
(ext. Zero Point Detector), der wiederum einen Timer Interrupt einstellt
und aktiviert. Beide Interrupts funktionieren auch tadellos jedoch
werden bei den Rücksprungen aus den Interrupts die jeweiligen If- und
While Schleifen an dem das Programm unterbrochen wurde bei dem
Rücksprung übersprungen
Z.B:
1
if(TASTE_M)
2
{
Ursache: Wenn ich beim Debuggen vor dem Sprung die Adresse im Programm
Counter ansehe lautet sie 0x72. Bei dem Sprung in den Interrupt wird sie
auf 0x74 erhöht. Daher wird die Schleife übersprungen. Ändere ich den
Rücksprungwert auf 0x72 spring das Programm wieder dahin wo es soll und
die If-Bedingung wird wieder korrekt abgefragt.
Gibt es eine Einstellung mit der man die Rücksprungadresse ohne eine
Erhöhung im Stack speichern kann?
hier mal ein Auszug aus meinem Programm:
Das sei() ist ja nötig um die Interrupt wieder zu aktivieren
(SREG=0x80). Nach jedem Interrupt wird SREG zurückgesetzt und wenn ich
das sei() nicht mache wird der Interrupt nur einmal ausgeführt.
Matthias S. schrieb:
> Das sei() ist ja nötig um die Interrupt wieder zu aktivieren> (SREG=0x80). Nach jedem Interrupt wird SREG zurückgesetzt und wenn ich> das sei() nicht mache wird der Interrupt nur einmal ausgeführt.
Welcher Compiler überhaupt? GCC? Dann sind die Interrupt-Routinen nicht
richtig definiert, was auch der Grund dafür ist, dass du
fälschlicherweise ein sei am Ende brauchst (weil deine Funktionen so
nämlich nur ein ret statt eines reti am Ende haben).
> (While und If-Schleifen)> die jeweiligen If- und While Schleifen
Es gibt nach wie vor keine If-Schleifen ...
Das einzige was mit If möglich ist, ist eine Abfrage.
> hier mal ein Auszug aus meinem Programm: ...
Hast du irgendwelche asm-Zeilen (Inline-Assembler) in den Programm?
Andreas W. schrieb:
> normalerweise sollte Dein Compiler am Ende der Interuptfunktion den> Befehl: "reti" setzen
Außer halt, der Compiler weiß gar nicht, dass es Interruptfunktionen
sind, so wie in diesem Fall.
Matthias S. schrieb:
> Ja, ich Arbeite mit dem AVR_Studio -> GCC,>> bei mir bringt der Befehl reti leider nicht und bei ret schimpft der> Compiler.
Du sollst den auch nicht selber einfügen, sondern die Interrupt-Funktion
korrekt deklarieren.
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
Stefan Ernst schrieb:
> Zusatz:> Das dürfte auch der Grund für das beobachtete Fehlverhalten sein, denn> die Interrupt-Funktionen sichern so auch die Register nicht korrekt.
Das hab ich anfangs auch gedacht, aber der Inhalt vom Stackpointer zeigt
während der Interruptroutine schon auf den nächsten Befehl.
PC
0x72 if(TASTE_M) //-> Sprung in den Interrupt (SP=0x74)
{
0x74 i++; //<-Rücksprung aus dem Interrupt
Das sei() hab ich erstmal wieder weggenommen.
Wer weiss, vielleicht ist das bei Interrupts immer so. Anderswo (ARM)
ist das normal. Also mach richtige Interrupt-Handler aus deinen falschen
Interrupt-Handlern und diskutier nicht mit der Hardware wer Recht hat.
Die ist garantiert sturer.
Matthias S. schrieb:
> Das hab ich anfangs auch gedacht, aber der Inhalt vom Stackpointer zeigt> während der Interruptroutine schon auf den nächsten Befehl.
Das ist völlig normal und korrekt so. Wenn dein Programm sich nicht so
verhält, wie von dir erwartet, hat das damit rein gar nichts zu tun.
Hast du die Interrupt-Funktionen denn inzwischen mal korrigiert?
Matthias S. schrieb:
> (ext. Zero Point Detector), der wiederum einen Timer Interrupt einstellt> und aktiviert. Beide Interrupts funktionieren auch tadellos
Wobei ich mich trotzdem immer noch wundere, wieso deine Funktionen (den
das sind keine Interrupt Handler, die müssen spezielle Funktionsheader
haben) überhaupt aufgerufen werden.
Karl heinz Buchegger schrieb:
> Matthias S. schrieb:>> (ext. Zero Point Detector), der wiederum einen Timer Interrupt einstellt>> und aktiviert. Beide Interrupts funktionieren auch tadellos>> Wobei ich mich trotzdem immer noch wundere, wieso deine Funktionen (den> das sind keine Interrupt Handler, die müssen spezielle Funktionsheader> haben) überhaupt aufgerufen werden.
Das hab ich mich anfangs auch drüber gewundert aber es hat ja bis auf
den Rücksprung vor div. Schleifen und If-Abfragungen funktioniert
Karl heinz Buchegger schrieb:
> Matthias S. schrieb:>> (ext. Zero Point Detector), der wiederum einen Timer Interrupt einstellt>> und aktiviert. Beide Interrupts funktionieren auch tadellos>> Wobei ich mich trotzdem immer noch wundere, wieso deine Funktionen (den> das sind keine Interrupt Handler, die müssen spezielle Funktionsheader> haben) überhaupt aufgerufen werden.
Weil auch ohne das "ISR" der Name der Funktion vom Präprozessor in die
Vektornummer übersetzt wird.
Keine Sorge, da wäre später noch viel mehr merkwürdiger Blödsinn
passiert, wie beispielsweise Variablen die zufällig und mysteriös ihren
Wert ändern. Der Unterschied zwischen Funktionen und ISRs beschränkt
sich nicht auf das I-Flag und die Korrektur der Return-Adresse.
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.