Forum: Mikrocontroller und Digitale Elektronik Timer-Interrupt in C


von Sebastian (Gast)


Lesenswert?

Hallo Leute,

Mit Hilfe eines Timer-Interrupt (Overflow) möchte ich einen Teil des 
Hauptprogramms (eine Regelung) aufrufen.

Meine erste Idee, war das Setzen einer Flag.
1
// Timer-Interrupt
2
ISR (TIMER1_OVF_vect)
3
{flag = 1;}
4
5
// ...
6
7
sei();
8
9
int main (void)
10
11
while (run)
12
13
if (flag == 1)
14
{ 
15
// Regelung
16
flag = 0;
17
}

Leider hat das Ganze nicht so gut geklappt. Die Regelung ist zu langsam.
Ich vermute, dass das Programm die Regelungs-Routine nicht abarbeiten 
kann, bevor wieder ein Interrupt ausgelöst wird und er wieder von vorne 
beginnt.

Sollte ich das Interrupt lieber mit
1
cli ()
 sperren?
Oder kennt jemand einen ganz anderen Ansatz?

Gruß Seb
von Peter II (Gast)


Lesenswert?

Sebastian schrieb:
> Ich vermute, dass das Programm die Regelungs-Routine nicht abarbeiten
> kann, bevor wieder ein Interrupt ausgelöst wird und er wieder von vorne
> beginnt.

warum sollte sie denn wieder von vorne beginnen, nach den Interupt geht 
es an der gleichen stelle weiter wie vor dem interupt. Wenn die 
Regelungs-Routine fertig ist, dann wird sich gleich ein weiteres mal 
aufgerufen.
von NurEinGast (Gast)


Lesenswert?

Wenn Dein Programm die Regelung nicht durcharbeiten kann bevor ein 
weiterer Timerüberlauf kommt, dann hilt es auch nichts den Interrupt zu 
sperren.

1.) Dann weisst Du gar nicht mehr wie oft die Regelung wirklich 
aufgerufen
wird.
2.) Wenn am ende der Regelung der IRQ wieder freigegeben wird, dann wir 
die Regelung beim nächsten Hauptprogrammdurchlauf wieder aufgerufen. 
Also würde die Regelunf eh bei jedem Hauptprogramm durchlauf laufen - 
dann kannst Du den Timer gleich weglassen.

Entweder schaffst Du es die Regelung zwischen zwei Timerüberläufen 
fertig zu rechnen, oder du musst die Zeit zwischen zwei Interrupts 
erhöhen.

Duch ein CLI wird ja nicht schneller.
von Sebastian (Gast)


Lesenswert?

NurEinGast schrieb:
> Entweder schaffst Du es die Regelung zwischen zwei Timerüberläufen
> fertig zu rechnen, oder du musst die Zeit zwischen zwei Interrupts
> erhöhen.

Danke für die Antwort.

Der Lösungsvorschlag hört sich interessant an, besonders die 
Zeiterhöhung zwischen den Interrupts. Leider ist der Zeitpunkt des 
Overflow fix. Hiermit wird eine PWM gesteuert.
Kann ich für diese Anwendung Timer2 verwenden und insofern definieren, 
dass hier nach einem Overflow die Regelung aufgerufen wird?
von Michael (Gast)


Lesenswert?

Sebastian schrieb:
> Kann ich für diese Anwendung Timer2 verwenden und insofern definieren,
> dass hier nach einem Overflow die Regelung aufgerufen wird?

Es ist ja nicht zwingend, das bei jedem Timer-ISR die Regelung 
aktiviert wird. Aber unabhängige Timer würden auch gehen.
von Sebastian (Gast)


Lesenswert?

Michael schrieb:
> Es ist ja nicht zwingend, das bei jedem Timer-ISR die Regelung
> aktiviert wird.

zwingend nicht, aber wie kann man denn bei jedem z.B. fünften Overflow 
die Regelung aktivieren?
von Peter II (Gast)


Lesenswert?

Sebastian schrieb:
> zwingend nicht, aber wie kann man denn bei jedem z.B. fünften Overflow
> die Regelung aktivieren?

einfach 0 bis 4 Zählen und dann nur das Flag auf 1 setzen.
von XXX (Gast)


Lesenswert?

Hallo

Einfach mitzaehlen:

Erster Overflow
Zweiter Overflow
Dritter Overflow
Vierter Overflow
Fünfter Overflow   --> Mach was, beginne dann von vor´ne zu zählen

Gruß
Joachim
von Sebastian (Gast)


Lesenswert?

Also zum Beispiel:
1
// Timer-Interrupt
2
ISR (TIMER1_OVF_vect)
3
{flag ++;}
4
5
// ...
6
7
sei();
8
9
int main (void)
10
11
while (run)
12
13
if (flag == 5)
14
{ 
15
// Regelung
16
flag = 0;
17
}
von Andario (Gast)


Lesenswert?

Was für einen Controller verwendest Du denn?
Beim PIC zB muss man (wenn ich mich recht erinnere) das Interrupt-Flag 
in der ISR aktiv zurücksetzen, sonst bleibt es aktiv, der der Controller 
springt sofort wieder in die ISR zurück?

Grüße,
Andario
von Sebastian (Gast)


Lesenswert?

Andario schrieb:
> Was für einen Controller verwendest Du denn?

Atmel Atmega8

Ist der Code-Abschnitt denn so i.O.?
von ... (Gast)


Lesenswert?

Sebastian schrieb:
> Ist der Code-Abschnitt denn so i.O.?

Wenn du den so in den Compiler fütterst, wird der damit alleine wohl 
kaum glücklich. ;-).
von Sebastian (Gast)


Lesenswert?

... schrieb:
> Wenn du den so in den Compiler fütterst, wird der damit alleine wohl
> kaum glücklich. ;-).

Hauptsache die Regelung funktioniert :)
von Michel (Gast)


Lesenswert?

Was kommt zu dem Programm noch hinzu?
Beansprucht das auch mehr Laufzeit, als die Periodendauer von 
TIMER1_OVF?
Dann wird die Regelung gelegentlich aussetzen, bis es zu einem Überlauf 
von flag gekommen ist, da flag möglicher weise getestet wird, wenn
flag == 4 und das nächste mal wenn
flag == 6.

Vorschlag:
1
if (flag >= 5)
2
{ 
3
   // Regelung
4
   cli();
5
   flag -= 5;
6
   sei();
7
   // oder, falls man den verlorenen Tick nicht nachholen möchte:
8
   // flag = 0; 
9
}
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.