Interrupt Problem bei Rücksprung (While und If-Schleifen)

OP #1368455
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:
1
int main()
2
{
3
...  
4
TCCR1B=0x02;
5
TIMSK=0x04;
6
//HW-Interrupt einstellen und aktivieren
7
MCUCR=0x0A;    //Int. Bedingungen einstellen
8
GIMSK=0x40;    //Int0 aktivieren
9
sei();      //HW-Int aktivieren
10

11
//Hauptprogrammschleife
12
  while(1)
13
  {
14
    if(TASTE_M)
15
    {
16
      merker=0;
17
      zeile = Zeichne_Pfeil(zeile);
18

19
  do{
20
  }while(TASTE_M);
21
  ...
22
    }
23
  return(0);
24
}
1
void INT0_vect(void)
2
{
3
alpha=0x01;
4
...
5
TCNT1H=0xFF; //Timerwert für Timer1
6
TCNT1L=0x38; //Timerwert für Timer1
7
sei();
8
}
1
void TIMER1_OVF_vect(void)
2
{
3
alpha++;
4
TCNT1H=0xFF;
5
TCNT1L=0x38;
6
...
7
sei();
8
}

MfG
Matthias
#1368476
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).
Moderator (Firma: Titel) Persönliche Seite #1368484
>  (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?
OP #1368515
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.
#1368527
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.
#1368538
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?
#1368546
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.
OP #1368551
Ja, dank den Hinweisen von 
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html 
funktionieren meine Int-Routinen nun. ich hab sie jetzt wie folgt 
umdeklariert:
1
ISR(INT0_vect)
2
{
3
  alpha=0x01;
4
  if(alpha==alpha_ein)
5
  {
6
    STELLER_2_LOW();
7
    STELLER_1_HI();
8
  }  
9
  TCNT1H=0xFF;
10
  TCNT1L=0x38;
11
  //reti();
12
}
13

14
ISR(TIMER1_OVF_vect)
15
{
16
  alpha++;
17
  TCNT1H=0xFF;
18
  TCNT1L=0x38;
19
  if(alpha==alpha_ein)
20
  {
21
    STELLER_2_LOW();
22
    STELLER_1_HI();
23
  }
24

25
  if(alpha==alpha_aus)
26
  {
27
    STELLER_1_LOW();
28
    STELLER_2_HI();
29
  }
30
}

Vielen Dank und MfG
Matthias
OP #1368558
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
#1368563
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.
#1368565
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.

Antwort schreiben

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.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.