Forum: Mikrocontroller und Digitale Elektronik INTERRUPT_PROBLEM


von TimerInterrupt_Problem (Gast)


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:

1
static int time=0;//für Zeit
2
unsigned int TASK=0;
3
char interrupt_jump;
4
SIGNAL(SIG_OVERFLOW0)
5
{
6
interrupt_jump=1;
7
TCNT0=0;
8
time++;
9
   if(time>1)
10
   {
11
time=0;
12
//erhöhe Funktionsindex
13
      if(TASK>1) TASK=0;
14
      else TASK++;
15
   }
16
switch(TASK)//Aufruf der Funktion
17
{
18
case 0: Funktion1();break;
19
case 1: Funktion2(); break;
20
default: TASK=0; break;
21
}
22
}
23
24
int main()
25
{
26
//initialisiere Timer-Counter
27
TCCR0|=0x03;
28
TCNT0=0;
29
TIMSK|=(1<<TOIE0);//erlaube interrupt
30
DDRB=0xFF;
31
LCD_Init();
32
LCD_Clear;
33
LCD_Gotoxy(0,0);
34
LCD_Write("Starte verschachtelte Funktion");
35
PORTB=0x01;
36
while(1){}; Backgroundschleife
37
}
38
39
void Funktion1()
40
{
41
cli();//sperre Interrupts 
42
for(;;)
43
{
44
PORTB=0x02;
45
loop_till_ISR();//bis zum Auftritt des ISR bleibe in der Schleife
46
}
47
}
48
void Funkton2()
49
{
50
cli();
51
for(;;)
52
{
53
PORTB=0x04;
54
loop_till_ISR();//bis zum Auftritt des ISR bleibe in der Schleife
55
}
56
}
57
58
void loop_till_ISR()
59
{
60
while(!interrupt_jump){ sei();}
61
cli();
62
interrupt_jump=0; 
63
}

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

von Tom M. (tomm) Benutzerseite


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

von Falk B. (falk)


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

von TimerInterrupt_Problem (Gast)


Lesenswert?

Oh ja her damit, bin gespannt darauf

von Falk B. (falk)


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)

von Tom M. (tomm) Benutzerseite


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.

von TimerInterrupt_Problem (Gast)


Lesenswert?

Stimmt. Möchte mich recht herzlich bei Falk bedanken;)

von TimerInterrupt_Problem (Gast)


Lesenswert?

Tom M. Hast recht hab ihn jetzt gerade mal durchgelesen

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.