Forum: Compiler & IDEs Variablen in Interrupts


von Boris (Gast)


Lesenswert?

Kurze Frage!

Wenn ich z.B. einen Overflow-Interrupt nutzen möchte....
und in dem Interrupt vier Variablen hochzähle, wie kann ich diese
Variablen in anderen Funktionen benutzen?
so wie es untensteht.... funktioniert es nicht.
Sind die Variablen nicht global?

volatile uint8_t timervar1;
volatile uint8_t timervar2;
volatile uint8_t timervar3;
volatile uint8_t timervar4;

SIGNAL (SIG_TIMER0_OVF) /*Dieser Interrupt löst beim Überlauf des
Timers0 aus*/
{
 timervar1++;      //erhöht die Variable um eins
 timervar2++;      //erhöht die Variable um eins
 timervar3++;      //erhöht die Variable um eins
 timervar4++;      //erhöht die Variable um eins
}
void abschalten ()
{
timervar1=0;
if(timervar1==50)  /*wenn diese Bedingung erfüllt ist wird         die 
PWM
auf Null gesetzt
   {
   PORTB =0x00;
        }
}

DANKE

von Werner B. (Gast)


Lesenswert?

1
void abschalten ()
2
{
3
   timervar1=0;
4
   while(timervar1 != 50)
5
       ;// Warte bis 50 Mal Overflow
6
7
   PORTB =0x00;
8
}

von peter dannegger (Gast)


Lesenswert?

1
timervar1=0;
2
if(timervar1==50)

Da brauchts dann einen weiteren Interrupt, der als INTERRUPT (mit
Interruptfreigebe) deklariert ist, der genau zwischen die beiden Zeilen
haut und genau 50 Timerüberläufe dauert, damit diese Bedingung war
wird.


Peter

von Boris (Gast)


Lesenswert?

Also kann ich ausserhalb der interrupt Routine auf die hochgezählte
Variable zugreifen und einen vergleich starten?

Bei mir funktioniert das nur wenn ich die Abschaltbedingung direkt in
die INTERRUPT-Routine reinschreibe.Ausserhalb funzt es nicht!

von Werner B. (Gast)


Lesenswert?

(Ganz geduldig)

Boris,

wenn Du jedesmal VOR dem Abfragen ob timervar1 den Wert 50 hat, den
Wert von timervar1 auf 0 setzt, wird diese Bedinung NATÜRLICH *NIE*
erfüllt!
Zudem solltes Du auf "if(timervar1 >= 50)" prüfen.

von Boris (Gast)


Lesenswert?

Also folgendes Programm funktioniert nicht:
volatile uint8_t x;

SIGNAL (SIG_TIMER0_OVF) /*Dieser Interrupt löst beim Überlauf des
Timers0 aus*/
{
 x++;      //erhöht die Variable um eins
}
int main (void) //HAUPTPROGRAMM
{
init(); //INIT
sei();    //INTERRUPTS aktiv
if (x==50)
    {PORTB|=(1<<PB7)}
}

So und folgendes Programm funktioniert
volatile uint8_t x;

SIGNAL (SIG_TIMER0_OVF) /*Dieser Interrupt löst beim Überlauf des
Timers0 aus*/
{
 x++;
if (x==10)               //erhöht die Variable um eins
    {PORTB|=(1<<PB7)}
}
int main (void) //HAUPTPROGRAMM
{
init(); //INIT
sei();    //INTERRUPTS aktiv

}

WARUM kann ich nicht die IF-BEDINGUNG in das HAUPTPROGRAMM schreiben?
Meine Interrupt wird ausgelöst...daran kann es nicht liegen,....!

Habt Ihr neh Idee?
ist volatile falsch?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> WARUM kann ich nicht die IF-BEDINGUNG in das HAUPTPROGRAMM
> schreiben?

Repariere erstmal deine CAPSLOCK-Taste, bevor du hier herumschreist.

Es wäre zuweilen auch nützlich, wenn du deinen Prozessortyp mit
dazuschreibst.  Ist offenbar ein ATtiny2313, ja?

> Habt Ihr neh Idee?

Ja.  Weil x eben an der Stelle, wo du es testest, nicht gleich 50 ist.
Du testest es nur einmal.  Danach fällst du ,,ins Leere'', also in
eine Endlosschleife, die sich hinter der Funktion exit() verbirgt, die
implizit am Ende von main() aufgerufen wird.  Das ist vermutlich nicht
ganz das, was du tun wolltest.

von Fritz G. (fritzg)


Lesenswert?

Das tut:
1
int main (void) //HAUPTPROGRAMM
2
{ 
3
init(); //INIT
4
sei();    //INTERRUPTS aktiv
5
6
while (1)
7
 { 
8
  if (x==50)
9
     {PORTB|=(1<<PB7)}
10
 }
11
}

von Boris (Gast)


Lesenswert?

Mhhh!
Jetzt habe ich das Programm so wie oben beschreiben.

Jedoch habe ich das Gefühl, das mein Programm die Variable in der MAIN
gar nicht kennt!

von Fritz G. (fritzg)


Lesenswert?

Dann müsste der Compiler meckern. Natürlich darfst du in main kein x
deklariert haben.

von Boris (Gast)


Lesenswert?

deklariere kein x in Main!
also wenn die bedingung direkt ins Interrupt schreibe dann geht!
Komisch?

von Karl H. (kbuchegg)


Lesenswert?

Boris.
Dein Problem ist ein ganz anderes.

Wenn Du die Bedingung ins Hauptprogramm schreibst,
dann musst Du schon darauf warten, dass x irgendwann den
Wert 50 erreicht.

> SIGNAL (SIG_TIMER0_OVF) /*Dieser Interrupt löst beim Überlauf des
>                           Timers0 aus*/
> {
>  x++;      //erhöht die Variable um eins
> }
> int main (void) //HAUPTPROGRAMM
> {
>   init(); //INIT
>   sei();    //INTERRUPTS aktiv
>   if (x==50)
>   {
>     PORTB|=(1<<PB7)
>   }
> }

Sie mal:
Nach dem sei bginnt der Timer zu tickern. Sagen wir mal
er wird das erste mal aufgerufen: x wird um 1 erhoeht und
hat jetzt den Wert 1.
Super, Aber gleich nachdem der Timerinterrupt durchgelaufen ist,
wird auch im Hauptprogram wieder weitergemacht:

   if( x == 50 )

x hat aber nicht den Wert 50. x ist erst bei 1. Und daher wird
der if Teil nicht gemacht. Und weiter gehts im Hauptprogram.
Nur da ist nichts mehr (was macht ein AVR eigentlich in so einem
Fall). Waehrenddessen kommt der naechste Timer Interrupt.
x kriegt den Wert 2. Super. Nur ist da im Hauptprogram nichts
mehr was sich dafuer interessieren wuerde. Dein main() ist
ja schon lange beendet. Naechster Timer Interrupt. x kriegt
den Wert 3, usw. Irgendwann hat x dan den Wert 50 erreicht.
Auch gut. Nur im Hauptprogramm interessiert das keine Sau mehr,
der Code der x ueberprueft ist schon lange durch und da er nicht
wiederholt wird, ....

Du musst die Abfrage in eine Schleife packen, die immer und
immer wieder durchlaufen wird.

   while( 1 ) {

     if( x == 50 ) {
       /* mach was */
     }
   }

-----

> So und folgendes Programm funktioniert
> volatile uint8_t x;
>
> SIGNAL (SIG_TIMER0_OVF) /*Dieser Interrupt löst beim Überlauf des
                            Timers0 aus*/
> {
>   x++;
>   if (x==10)               //erhöht die Variable um eins
>     {PORTB|=(1<<PB7)}
> }

Ist ja auch klar. Hier wird ja jedesmal, wenn x erhoeht wird,
auch gleichzeitig die Abfrage gemacht, ob der Wert 10 erreicht
ist. Ist ja beides in der Interrupt Funktion. Da die Abfrage
aber immer gleichzeitig mit der Erhoehung gemacht wird, kann
der Wert von 10 auch nicht uebersehen werden.

Das hast Du aber nicht im ersten Fall. Da ist: Die Erhoehung
fundet in der Interrupt Funktion statt und die Abfrage in main().
Nur weiss der Teil in main() ja nicht wann die Erhoehung stattfindet
daher muss er drauf warten.

Wenn Du Dir mit Deinem Kumpel ausmachst, dass er Dir irgendwann
im Laufe des Nachmittags ein Buch auf dem Tisch liegen laesst,
dann wirst Du auch ein paarmal nachsehen muessen, ob er schon
da war. Wenn Du bereits um 13 Uhr nachsiehst, das Buch nicht
vorfindest und daraus den Schluss ziehst, dass man sich auf
Deinen Kumpel nicht verlassen kann, dann war das wohl etwas
voreilig. Die siehst vielleicht um 13:30 nochmal nach, dann um 14:00.
Sagen wir mal Dein Kumpel kommt um 14:10. Wenn Du dann um 14:30
wieder nachsiehst findest Du letztendlich das Buch.

von Stefan Kleinwort (Gast)


Lesenswert?

@Karl Heinz:
Du bekommst den goldenen Gedulds-Engel verliehen :-)

Gruß, Stefan

von Boris (Gast)


Lesenswert?

@Karl Heinz!
Vielen Dank für die ausführliche Auskunft. Ich bin dir sehr dankbar!
Es funktioniert jetzt so wie soll!
Schön das es solche geduldigen Leute hier im Forum gibt.....Ohne Euch
wären Anfänger wie ICH aufgeschmissen!
Schönen Abend

Boris aus Paderborn!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Warum hast du dir meine Antwort nicht durchgelesen?

von Boris (Gast)


Lesenswert?

Hey Jörg....Natürlich habe ich auch dein Eintrag geslesen!
Auch dir DANKE!

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.