www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik INTERRUPT_PROBLEM


Autor: TimerInterrupt_Problem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!!!



Möchte 2 Funktionen zeitlich verschachtelt nacheinander aufrufen (=nach 
2ms), bei Frequenz von 4 MHz, funktioniert alles prima, bis auf das, 
dass nach dem fünften bzw. 6.Mal wieder alles initialisiert wird und von 
Anfang an abexekutiert wird.
Meine Frage an euch: Kann ich dies irgendwie vermeiden?

Bitte nicht auslachen, bin voll am Grübeln, finde jedoch keine Lösung.


siehe Code:

static int time=0;//für Zeit
unsigned int TASK=0;
char interrupt_jump;
SIGNAL(SIG_OVERFLOW0)
{
interrupt_jump=1;
TCNT0=0;
time++;
   if(time>1)
   {
time=0;
//erhöhe Funktionsindex
      if(TASK>1) TASK=0;
      else TASK++;
   }
switch(TASK)//Aufruf der Funktion
{
case 0: Funktion1();break;
case 1: Funktion2(); break;
default: TASK=0; break;
}
}

int main()
{
//initialisiere Timer-Counter
TCCR0|=0x03;
TCNT0=0;
TIMSK|=(1<<TOIE0);//erlaube interrupt
DDRB=0xFF;
LCD_Init();
LCD_Clear;
LCD_Gotoxy(0,0);
LCD_Write("Starte verschachtelte Funktion");
PORTB=0x01;
while(1){}; Backgroundschleife
}

void Funktion1()
{
cli();//sperre Interrupts 
for(;;)
{
PORTB=0x02;
loop_till_ISR();//bis zum Auftritt des ISR bleibe in der Schleife
}
}
void Funkton2()
{
cli();
for(;;)
{
PORTB=0x04;
loop_till_ISR();//bis zum Auftritt des ISR bleibe in der Schleife
}
}

void loop_till_ISR()
{
while(!interrupt_jump){ sei();}
cli();
interrupt_jump=0; 
}

Reaktion: Nach 5 bis 6 mal der Exekutation dieser Zeitscheibe löscht er 
wieder das LCD und schreibt wieder "Starte verschachtelte Funktion.

Ich will dies vermeiden.
Habs schon mit einer globalen Variable "start" versucht, die am an 
Anfang auf true gesetzt wird, die nicht rückgesetzt wird und dann Endlos 
lange Funktion 1 und 2 aufgerufen wird, jedoch vergeblich, er macht dies 
trotzdem...

Als µC hab ich einen atmega32;)

Hoffe ihr könnt mir helfen

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TimerInterrupt_Problem schrieb:

> unsigned int TASK=0;
> char interrupt_jump;

Du ändernst Variablen in der ISR. Das muss der Compiler unbedingt 
wissen: volatile verwenden!

Bei diesem Scheduler gefällt mir nicht, dass die "Tasks" (Functions) 
innerhalb der ISR abgearbeitet werden. Dadurch müsste die ISR sowie alle 
Tasks re-entrant sein, sonst klemmt's sobald ein Task blockiert oder 
halt mal etwas mehr erledigen muss....

IMO ist es besser, in der ISR nur Counter/Flags zu verwalten die 
anzeigen, welche Functions ASAP/wieder mal auszuführen sind. Die 
Ausführung übernimmt dann ein "Dispatcher" Loop in der main(). Wenn du 
willst, kann ich dir eine kleine Lib dazu liefern. Sie basiert auf 
diesem Code:

http://www.avrtutor.com/tutorial/scheduler/testscheduler.php

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  TimerInterrupt_Problem (Gast)

>Möchte 2 Funktionen zeitlich verschachtelt nacheinander aufrufen (=nach
>2ms), bei Frequenz von 4 MHz, funktioniert alles prima,

WIRKLICH?

> bis auf das,
>dass nach dem fünften bzw. 6.Mal wieder alles initialisiert wird und von
>Anfang an abexekutiert wird.

Tolles Wort "abexekutiert".

>Meine Frage an euch: Kann ich dies irgendwie vermeiden?

Du hast nicht nur Probleme mit der Rechtschreibung, sondern auch mit 
grundlegenden Programmierkonzepten.

Siehe Interrupt und Multitasking.

>Bitte nicht auslachen, bin voll am Grübeln, finde jedoch keine Lösung.

Lass diese sinnlosen cli(), sei() und loop_till_ISR() Unsinn!!!
Das kann man alles SEHR SAUBER in der Hauptschleife machen.

MfG
Falk

Autor: TimerInterrupt_Problem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh ja her damit, bin gespannt darauf

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  TimerInterrupt_Problem (Gast)

>Oh ja her damit, bin gespannt darauf

Nur selber lesen und denken macht geistig fett.

(Schöner Spruch von meinem Mathelehrer)

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TimerInterrupt_Problem:
> Oh ja her damit, bin gespannt darauf

Der code von avrtutor ist wirklich gut erklärt, da kann ich mit meinem 
nicht mithalten und Support leiste ich auch keinen... ;) Fang einfach 
damit an, die Initialisierung in InitScheduler() anzupassen. Wenn das 
Programm dann mal läuft, kannst du nach Belieben eigene Functions 
reinbauen. Funzt prima.

Happy Hacking! :)


Falk Brunner:
> Nur selber lesen und denken macht geistig fett.

:D Gefällt mir.

Autor: TimerInterrupt_Problem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt. Möchte mich recht herzlich bei Falk bedanken;)

Autor: TimerInterrupt_Problem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom M. Hast recht hab ihn jetzt gerade mal durchgelesen

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.