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:
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?
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.
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...
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)
...
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
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.
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
Eine eigene Frage?
Dieser Thread ist über 16 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.