Hallo,
ich hab ein kleines Problem mit den Interrupts bei meinem Atmega48.
Und zwar sprinngt mir das Programm nach einem Timerinterrupt nicht mehr
zurück in die main Funktion. Ist das normal?
Ich hab auch schon versucht mit reti() wieder zurück zu springen, aber
dann land ich wieder ganz am Anfang von main, also noch vor der
Initialisierung der Timer und Interrupts. Das ist dann auch nicht Sinn
der Sache.
Gibt es da eine andere Lösung oder muss ich mich irgendwie von Interrupt
zu Interrupt durchmogeln?
Was passiert eigentlich wenn ein Interrupt von einem Anderen
unterbrochen wird? Hab keine Prio für die Interrupts gefunden. Vor allem
springt er dann wenigstens in die unterbrochene Funktion zurück oder ist
da dann das gleiche Problem?
Danke im Voraus für die Mühe
p.s. ich programmier in C mit avrstudio 4
Hi Hans,
ohne Code wird das nur ein Ratespiel. Deine Fragen versuche ich trotzdem
mal zu beantworten:
> Und zwar sprinngt mir das Programm nach einem Timerinterrupt nicht mehr> zurück in die main Funktion. Ist das normal?
Das hängt davon ab, was in der ISR steht (z.B. eine Endlosschleife?).
> Ich hab auch schon versucht mit reti() wieder zurück zu springen, aber> dann land ich wieder ganz am Anfang von main, also noch vor der> Initialisierung der Timer und Interrupts.
"reti" solltest Du in einer ISR in C auch nicht hinzufügen.
> Gibt es da eine andere Lösung oder muss ich mich irgendwie von Interrupt> zu Interrupt durchmogeln?
Durchmogeln? Der uC macht nur, was Dein Programm ihm sagt.
> Was passiert eigentlich wenn ein Interrupt von einem Anderen> unterbrochen wird? Hab keine Prio für die Interrupts gefunden.
Verwendest Du "ISR()"? Dann wird nichts unterbrochen. Wenn während der
ISR ein weiterer Interrupt gesetzt wird, kehrt das Programm zunächst zu
dem Punkt+1 zurück, wo es unterbrochen wurde, dann zur zweiten ISR.
Mehr kann ich ohne Code nicht helfen.
Gruß
Fred
Danke Fred
im code steht eignetlich noch nix interresantes drin. also nur die paar
haeder, die main funktion, eine init() zur Belegung der register für
Timer und Interrupts und die paar ISR() Funktionen.
int Zeitbasis;
int main(void){
init();
while(1)
{
// hier solln noch viel entstehn :)
while(Zeitbasis < 98){} // warten bis 10 ms vergangen sind
// HIER KOMM ICH NICHT MEHR HIN
Zeitbasis = 0;
}
return 0;
}
ISR(TIM0_vect){
Zeitbasis++;
}
die init() und die header spar ich mir mal, sind ja normal standard
Hallo Hans,
nur eben mal auf die Schnelle:
1. Wo ist denn Dein TIM0_vect definiert? Welche WinAVR Version
verwendest Du? Für den ATmega48 kenne ich nur die folgenden
Timer0-Interrupt-Vektoren:
TIMER1_OVF_vect
TIMER0_COMPA_vect
TIMER0_COMPB_vect
TIMER0_OVF_vect
2. Zeigst Du uns bitte die Initialisierung des Timers?
Viele Grüße
Fred
hast recht
hab den code ausm Gedächtnis geschrieben, heißt natürlich
TIMER0_OVF_vect und steht in iomx.h
TCCROA=0x00;
TCCR0B=0x02; //2500kHz
TCNT0=0X00;
OCR0A=0x00;
OCR0B=0x00;
TIMSK0=0x01;
hab aber auch schon viel langsamer versucht, hat auch nix gebracht
Zeitbasis ist nicht volatile deklariert, wird aber in main und in der
ISR benutzt. Da wird der Optimizer reinhauen...
BTW: Nächstes Mal bitte nur einmal posten...
Zusätzlich zu den Fragen von Fred S. fällt mir das fehlende volatile
bei int Zeitbasis; auf. Ohne volatile Kennzeichnung geht der Compiler
davon aus, dass sich Zeitbasis in main nie ändert. Möglicherweise
hat Sven Pauli das gemeint mit dem Optimierer.
> die init() und die header spar ich mir mal, sind ja normal standard
Standard hin oder her. Den obenstehenden Code kann man jedenfalls nicht
in der eigenen Toolchain übersetzen oder für den Atmega48 simulieren.
Aber wie du meinst - du suchst Hilfe, nicht "wir" ;-)
die init ist mit der Timerkonfiguration eigentlich schon fast komplett,
da fehlt nur noch sei();
und Zeitbasis=0;
zu den Headern
<stdint.h>
<avr/interrupt.h>
<avr/io.h>
<inttypes.h>
wo muss das volatile eigentlich genau hin hab alle positionen
ausprobiert, ohne Erfolg.
Zeitbasis wird auch hochgezählt, es zählt aber über die 98 drüber ohne
aus der while zu fliegen
> wo muss das volatile eigentlich genau hin hab alle positionen> ausprobiert, ohne Erfolg.
In die Deklaration:
volatile int Zeitbasis;
> Zeitbasis wird auch hochgezählt, es zählt aber über die 98 drüber ohne> aus der while zu fliegen
Bitte poste mal den echten Code, entweder als Anhang oder per
Cut&Paste, und keine aus dem Gedächtnis hingeschriebene Fragmente.
Hallo Hans,
die Deklaration und Verwendung von "Zeitbasis" ist in Ordnung. Woran
kannst Du aber überhaupt erkennen, dass der Programmzeiger in der ISR
stecken bleibt, wie Du im ersten Posting geschrieben hast?
Übrigens: Schöner wäre es, wenn Du den Code mit symbolischen Bitnamen
und Kommentaren schriebst, z.B.:
ich hab einen Haltepunkt im Interrupt und beobachte wie die zeitbasis
hochgezählt wird.
OHH mist mir ist bei der ganzen testerrei eine codezeile verloren
gegangen.
nach der while ( Zeitbasis <98){}
war mal
Zeitbasis = 0;
ok dann wars doch das volatile
danke an alle, war echt super von euch
nur noch eine kleine frage wenn ich schonmal dabei bin. Muss ich
operationen iin der ISR vor Unterbrechungen schützen z.b. mit atomic?
Hallo Hans,
na also -- ging doch!
> nur noch eine kleine frage wenn ich schonmal dabei bin. Muss ich> operationen iin der ISR vor Unterbrechungen schützen....
Nein, ist bei der ISR nicht nötig... es sei denn, Du hast ein ein
"sei();" in der ISR!
Gruß
Fred