Atmega8 - Timer1 Interrupt-Behandlung wird nicht beendet

OP #2944432
Lesenswert?

Hallo,

ich lerne gerade die Programmierung von Microcontrollern. Bei der 
Implementierung eines Sekundenzählers (Timer1) mittels Interrupt stoße 
ich auf folgende Problematik:

Der Timer 1 soll einen Interrupt bei einem Buffer-Overflow auslösen. Der 
Zähler wird mit Prescaler (1024) und einem Startwert parametriert. Die
Interrupt-Serviceroutine soll den Timer stoppen und die Endlosschleife 
beenden.

Hier der Code-Ausschnitt:
1
#include <avr/io.h>
2
#include <stdio.h>
3
#include <avr/interrupt.h>
4

5
(...)
6

7
int wait(int i)
8
{
9
  
10
  for (int j = 0; j<= i; j++)
11
  {
12
    TCCR1A=0x00; // Normal port operation
13
    TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10);   
14
    TCNT1=61936; // Startwert des Timers
15
    TIMSK|=0x04; // Timer1 Overflow Interrupt = Enable
16
    
17
      
18
    while(sekunde=1)
19
    {
20
      //warten auf Interrupt
21
    }
22
                     /* Diese Stelle wird nie erreicht!*/    
23
    sekunde=1;
24
  }  
25
  
26
  
27
  return(0);
28
  
29
}
30

31
ISR(TIMER1_OVF_vect)
32
{
33
  TCCR1B=0x00;    //Timer:stop!
34
  TIMSK&=~(0x04); //Interrupt löschen
35
  sekunde=100;
36
  
37
}
Problem: Der Interrupt wird ausgelöst, die ISR wird bearbeitet. Nachdem 
die ISR abgearbeitet wird, wird a.) die ISR nicht verlassen b.) die 
(Endlos-) Schleife nicht beendet.
Da Ich nun schon mehrere Versuche (eine Variante ist oben zu sehen) 
unternommen habe, viele Code-Beispiele gesichtet habe, das Manual 
gequält habe aber meinen Fehler nicht sehe, bitte ich um Hilfe :-) .
Vielen Dank im Voraus!!!
Gast #2944457
Lesenswert?

Hans Meier schrieb:
> Hi, sorry sekunde ist mit "volatile int sekunde" deklariert.
Passt.


> Die
> (Endlos-) Schleife wird auch mit folgender Bedingung nie verlassen:
Äh ja natürlich wird sie bei while(1) nicht verlassen, aber das ist doch 
nicht das was du willst?!

Also zusammengefasst: Das Problem ist dass das Programm nach der ISR 
nicht weiterläuft richtig?? Das könnte dann ein Problem mit dem Stack 
oder so sein, aber daran glaube ich erstmal nicht.
OP #2944465
Lesenswert?

Du hast natürlich recht mit While{1}. Habe mich verm. schon etwas zu 
lange mit der Problematik beschäftigt.

Zu Punkt2:
Richtig. Die Interrupt-Routine wird bearbeitet bis zum Ende. Danach wird 
entweder die Interrupt-Routine nicht beendet oder die Schleife in der 
Methode wird nicht verlassen.

Zum restlichen Code:

Der Programm-Ablauf sieht es vor, eine gewisse Zeit (i-Sekunden) zu 
warten, bevor die nächste Methode abgearbeitet wird (Methode wait(int 
i). Die Methode wait zählt Sekunden, bis der Zielwert erreicht ist. Bei 
der ersten Sekunde stoppt die Zeitmessung, da der Programmablauf nicht 
fortgesetzt wird.
Ist diese Zeitperiode vorrüber, soll in die aufrufende Methode 
"gesprungen" werden.
Gast #2944533
Lesenswert?

Hans Meier schrieb:
> while(sekunde=1)

Falls es noch nicht klar geworden ist, das muss heißen:
1
while(sekunde==1)

Die Timer-Initialisierung brauchst Du nicht jedes Mal in der Schleife 
machen. Das reicht einmal zu Beginn des Programms.

Und ganz allgemein: Was Du da vorhast, sieht nach Unsinn aus. Statt der 
wait-Funktion kannst Du auch einfach delay_ms() benutzen. Der Timer ist 
dafür da, dass man eben kein Polling mehr betreiben muss à la:
1
while (!irgendwas) {
2
  // warte bis irgendwas eintritt
3
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren