Timer-Interrupt in C

Gast #2394290
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
Gast #2394294
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.
Gast #2394304
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.
Gast #2394317
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?
Gast #2394393
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
Gast #2394459
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren