mikrocontroller.net

Forum: Compiler & IDEs Variablen in Interrupts


Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void abschalten ()
{
   timervar1=0;
   while(timervar1 != 50)
       ;// Warte bis 50 Mal Overflow

   PORTB =0x00;
}

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
timervar1=0;
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

Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Fritz Ganter (fritzg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das tut:
int main (void) //HAUPTPROGRAMM
{ 
init(); //INIT
sei();    //INTERRUPTS aktiv

while (1)
 { 
  if (x==50)
     {PORTB|=(1<<PB7)}
 }
}

Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Fritz Ganter (fritzg)
Datum:

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

Autor: Boris (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz:
Du bekommst den goldenen Gedulds-Engel verliehen :-)

Gruß, Stefan

Autor: Boris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum hast du dir meine Antwort nicht durchgelesen?

Autor: Boris (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.