Forum: Mikrocontroller und Digitale Elektronik AVR Atmega32 while mit Timer Interrupt unterbrechen


von Luki (Gast)


Lesenswert?

Hallo,

ich bin noch relativ neu im uC programmieren und habe folgendes Problem.
Ich möchte eine while Schleife mit dem Overflow Interrupt meines Timers1
stoppen. Der Overflow Interrupt funktioniert wenn ich die while Schleife 
auskommentiere(und ein delay einfüge). Wenn er jedoch in der while 
Schleife ist, springt er nicht in den Interrupt bzw. er ruft ihn nicht 
auf (habs mit Breakpoints versucht).

Hier die Funktionen bzw. der Code:
1
static volatile char checkForOF;
2
3
void initTimer1(){
4
    TCCR1A &=~((1<<WGM10)|(1<<WGM11));   //normal Mode
5
    TCCR1B &=~((1<<WGM12)|(1<<WGM13));  
6
     TIMSK |= (1<<TOIE1);  //activates the overflow interrupt
7
}
8
9
void startMeasuring(){    
10
    unsigned int value;
11
    unsigned int oldADC=readADC();  
12
    unsigned int newADC;
13
    checkForOF=1;
14
    
15
    TCCR1B |= ((1<<CS10)|(1<<CS11));    
16
    TCCR1B &= ~(1<<CS12);  //start Timer 1
17
    
18
    while(checkForOF){  //as long as no interrupt
19
    newADC=readADC();    
20
    if(newADC>oldADC){    
21
      value=TCNT1;
22
      }
23
    }
24
    TCCR1B &=~ ((1<<CS12)|(1<<CS11)|(1<<CS10));//stop Timer 1
25
     TCNT1=0;            
26
}
27
28
ISR(TIMER1_OVF_vect){
29
  checkForOF=0;
30
}

Ich hoffe ihr könnt mir weiterhelfen.
Danke für eure Hilfe
Lukas

von Falk B. (falk)


Lesenswert?

@ Luki (Gast)

>Ich möchte eine while Schleife mit dem Overflow Interrupt meines Timers1
>stoppen.

Kann man machen. Das static ist eher nicht nötig.

> Der Overflow Interrupt funktioniert wenn ich die while Schleife
>auskommentiere(und ein delay einfüge). Wenn er jedoch in der while
>Schleife ist, springt er nicht in den Interrupt bzw. er ruft ihn nicht
>auf (habs mit Breakpoints versucht).

Vielleicht fehlt die Interruptfreigabe mit sei()?

>Hier die Funktionen bzw. der Code:

Stehen die alle in EINER Datei? Wenn nicht, ist das static hier 
kontraproduktiv.

>static volatile char checkForOF;

von guest (Gast)


Lesenswert?

Dann wird die nicht gezeigte readADC(); wohl die Interrupts sperren.

von Frederik H. (diveturtle93)


Lesenswert?

Ich könnte mir vorstellen, dass der Timer 1 falsch initialisiert wurde.

So sieht meine Initialisierung aus.
1
void init_Timer1(void)
2
{
3
  TCCR1A = 0;
4
  TCCR1B = 0;
5
  TIMSK = (1<<TOIE1);  //Timer1 Overflow Interrupt
6
  sei();               //Globale Interrupts avtivieren
7
  TCNT1 = 0;
8
}

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Luki schrieb:
> void initTimer1(){
>     TCCR1A &=~((1<<WGM10)|(1<<WGM11));   //normal Mode
>     TCCR1B &=~((1<<WGM12)|(1<<WGM13));
>      TIMSK |= (1<<TOIE1);  //activates the overflow interrupt
> }

Da sehe ich nichts von 'Normal Mode'. Das ist der 'Fast PWM' Mode mit 
OCR1A als TOP. Da OCR1A nicht initialisiert wird, steht es vermutlich 
auf null und erzeugt dadurch entweder gar keinen oder einen Regen von 
IRQs. Das steht aber auch so im Datenblatt.
Es ist übrigens gute Praxis, das TOV1 Flag einmal zu löschen, wenn man 
die Kiste initialisiert:
TIFR = (1 << TOV1);

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Matthias S. schrieb:
> Es ist übrigens gute Praxis, das TOV1 Flag einmal zu löschen, wenn man
> die Kiste initialisiert:
> TIFR = (1 << TOV1);

Es ist noch bessere Praxis, den Timer erst zu initialisieren, und dann 
zu starten, und ansonsten dem Datenblatt zu Folgen. Damit erübrigen sich 
alle fragwürdigen "gute Praxis" Tips.

Oliver

von Stefan F. (Gast)


Lesenswert?

Woher weisst du, dass der Timer-Interrupt auftritt, wenn du die while 
Schleife durch einen delay ersetzt?

In diesem Programmcode sehe ich keinen Test dafür. Hast du das nur 
geraten?

von Rainer B. (katastrophenheinz)


Lesenswert?

Der Codeschnipsel sieht ok aus, der Fehler liegt mMn woanders. Wie 
bereits oben gefragt: Hast du Interrupts überhaupt mal mit _sei() 
zugelassen bzw was macht readADC() ?

Zeig mal den gesamten Code!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Oliver S. schrieb:
> Es ist noch bessere Praxis, den Timer erst zu initialisieren, und dann
> zu starten, und ansonsten dem Datenblatt zu Folgen. Damit erübrigen sich
> alle fragwürdigen "gute Praxis" Tips.

Blablabla. Wieder mal prima aus dem Zusammenhang heraus zitiert. Zur 
Intialisierung habe ich davor was geschrieben, Dummquatscher.
Und einen pending IRQ vor dem Starten des Timers zu löschen, ist gute 
Praxis. Wie wärs einfach mal mit Schnauze halten, wenn man keine Ahnung 
hat?

von S. Landolt (Gast)


Lesenswert?

Matthias S. schrieb:
> Luki schrieb:
>> void initTimer1(){
>>     TCCR1A &=~((1<<WGM10)|(1<<WGM11));   //normal Mode
>>     TCCR1B &=~((1<<WGM12)|(1<<WGM13));
>>      TIMSK |= (1<<TOIE1);  //activates the overflow interrupt
>> }
>
> Da sehe ich nichts von 'Normal Mode'. Das ist der 'Fast PWM' Mode ...

Könnten Sie das näher erläutern?

von S. Landolt (Gast)


Lesenswert?

Ihn dünkt', er säh' den "normal mode",
ihm schien das sonnenklar.
Er guckt' noch mal und merkt, dass da
der Matze andrer Meinung war.
"Itzt wüsst ich gar zu gern," sprach er,
"lieg ich hier falsch, was ist nun wahr?"

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Is' ja gut, mein Fehler - Asche auf mein Haupt. Die Schreibweise ist 
allerdings wirklich ungewöhnlich.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.