Forum: Mikrocontroller und Digitale Elektronik STM32 Capture/Compare Interrupt deaktivieren


von Janis W. (jotwe)


Lesenswert?

Hallo,

ich würde gerne einen Capture/Compare Interrupt (z.B. TIM3 CC2) 
nachträglich deaktivieren, so dass das CCxIF Flag im SR Register nicht 
gesetzt wird. Damit soll verhindert werden, dass beim Auswerten des 
Interrupts, der z.B. durch TIM3 CC1 oder CC3 ausgelöst wird und durch 
die CCxIF Flags unterscheidet, welcher CC den Interrupt ausgelöst hat, 
die falsch Funktion mit ausgeführt wird.

Was diese Aufgabe nicht zu erfüllen scheint sind folgende Ansätze:
1
TIM_ITConfig(TIM3, TIM_IT_CC2, DISABLE); // Edit DIER Register

oder
1
TIM_SetCompare2(TIM3, 65000); // 65000 > ARR Register

Ich könnte natürlich noch eine eigene Flag bei der Abarbeitung des 
Interrupts benutzen, aber geht das nicht auch mit "Hausmitteln"?

Gruß

Janis

von bla (Gast)


Lesenswert?

Also wenn du den ersten von mehreren quasi zeitgleich aufgetretenen 
Capture interrupts bestimmen willst, brauchst du doch nur die CCR 
register vergleichen, dann die interrupt flags der "zu späten" 
interrupts von Hand zurücksetzen...

Oder willst du was anderes?

von Janis W. (jotwe)


Lesenswert?

Ich will eigentlich Interrupts deaktivieren. Konkret messe ich mit 3 CCs 
verschiedene Zeitabstände. CC2 ist dabei ein Timeout, den ich gerne 
deaktivieren würde, wenn das Ereignis früh genug eingetroffen ist. Aber 
es scheint wohl immer das CCxIF Flag im SR Register geschrieben zu 
werden, auch wenn das DIER Register anpasse oder den Capture-Wert für 
den Timer unerreichbar hoch setzte.

von Janis W. (jotwe)


Lesenswert?

Hm, das Problem scheint wohl nicht so einfach zu lösen zu sein oder ich 
schaffe es nicht es richtig zu erklären :) Jedenfalls hat mich bisher 
auch das Datenblatt dazu nicht schlauer gemacht...

von bla (Gast)


Lesenswert?

Also so wie ich die jetzt verstanden habe, wird das CC2IF flag gesetzt, 
auch wenn der dazugehörige interrupt im DIER deaktiviert ist (ist das 
wirklich so? schon seltsam...).
Es wird dann aber kein interrupt ausgelöst.

Nun störst du dich beim abarbeiten eines anderen interrupts über das 
gesetzte flag? Kannst du nicht einfach zusätzlich zu dem flag prüfen, ob 
der dazugehörige interrupt aktiviert ist? Wenn er es nicht is, kann er 
ja nicht der auslöser gewesen sein...

if((TIMx->SR & TIM_SR_CC2IF) && TIMx->DIER & TIM_DIER_CC2IE)
...

von Janis W. (jotwe)


Lesenswert?

Danke für Deine Antworten! Genau das ist das von mir beobachtete 
Verhalten: Es wird das CC2IF Flag gesetzt, aber kein Interrupt 
ausgelöst. Vielleicht ist das für Leute, die Polling machen... keine 
Ahnung.

Dein Lösungsvorschlag funktioniert solange, wie der Interrupt 
deaktiviert ist. Sobald ich ihn wieder aktiviere und ein beliebiger CC 
einen Interrupt auslöst, z.B. CC1, wird auch wieder die Funktion von CC2 
fälschlicherweise ausgeführt, da das CC2IF Flag ja noch gesetzt ist.

Für mich wäre es am einfachsten, wenn ich dieses Setzten des CC2IF Flags 
unterbinden könnte. Aber da habe ich noch keine Möglichkeit gefunden...

Ansonsten fällt mir nur ein, das CC2IF Flag in der main-Schleife ständig 
zu löschen. Wenn es dann gewollt mit Interrupt auftritt, müsste der 
Interrupt (hoffentlich) vor dem Löschen aufgerufen und abgearbeitet 
werden... Naja, aber das ist recht "unsauber" :)

Gruß

Janis

von (prx) A. K. (prx)


Lesenswert?

Janis W. schrieb:

> deaktiviert ist. Sobald ich ihn wieder aktiviere und ein beliebiger CC
> einen Interrupt auslöst, z.B. CC1, wird auch wieder die Funktion von CC2
> fälschlicherweise ausgeführt, da das CC2IF Flag ja noch gesetzt ist.

Und wenn du das IF direkt vor dem Einschalten des Interrupts löschst?

> Für mich wäre es am einfachsten, wenn ich dieses Setzten des CC2IF Flags
> unterbinden könnte. Aber da habe ich noch keine Möglichkeit gefunden...

Peripheriemodule sind meistens so wie hier konstruiert. Das IF dient als 
genereller Ereignisindikator, unabhängig davon ob die Interrupts nun 
eingeschaltet sind oder nicht.

von Janis W. (jotwe)


Lesenswert?

A. K. schrieb:
> Und wenn du das IF direkt vor dem Einschalten des Interrupts löschst?

Äh ja, der Vorschlag ist simpel und gut... und ich wundere mich gerade, 
dass ich da nicht selbst drauf gekommen bin. Liegt wohl an der 
fortgeschrittenen Stunde :)

> Peripheriemodule sind meistens so wie hier konstruiert. Das IF dient als
> genereller Ereignisindikatur, unabhängig davon ob die Interrupts nun
> eingeschaltet sind oder nicht.

Das ist gut zu wissen. Ich war eben schon daran etwas Entsprechendes in 
der Errata-Dokumentation zu suchen. Aber wenn das so gewollt ist...

Vielen Dank für die Antworten. Ich werde das dann morgen hoffentlich 
endlich zum Laufen bringen.

Schönen Abend noch!

Janis

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.