Ist es wirklich notwendig, das XMEGA-Timer-Overflow-Interrupt-Flag manuell zu löschen?

Wie einige von Ihnen vielleicht wissen, bietet Atmel ein Software-Framework (hauptsächlich als Teil von Atmel Studio) an, das Treiber und Beispiele bereitstellt und mehr oder weniger regelmäßig aktualisiert wird.

In einem kürzlich erschienenen Update weisen sie ausdrücklich darauf hin, dass es wichtig ist , das Überlauf-Interrupt-Flag in der Interrupt-Callback-Funktion manuell zu löschen.

 // * \subsection xmega_tc_qs_ovf_setup_code Example code
 // *
 // * Add a callback function that will be executed when the overflow interrupt
 // * trigger.
 // * \code
 static void my_callback(void)
 {
    // User code to execute when the overflow occurs here

    // THIS WAS ADDED IN LAST UPDATE
    // Important to clear Interrupt Flag
    tc_clear_overflow(&TCC0);
    // THIS WAS ADDED IN LAST UPDATE

 }
 //\endcode

Laut XMEGAA-Datenblatt:

OVFIF wird automatisch gelöscht, wenn der entsprechende Unterbrechungsvektor ausgeführt wird. Das Flag kann auch gelöscht werden, indem eine Eins an seine Bitstelle geschrieben wird.

Gibt es ein Szenario/einen Grund, wo das manuelle Löschen des Flags erforderlich sein kann?

klingt wie die Antwort ist, wenn Sie nicht unterbrechen, dann müssen Sie es manuell löschen. im Wesentlichen wenn/wenn Abfragen statt Interrupts zu verwenden. Sie können das Register einfach im Interrupt lesen und es irgendwie anzeigen, um zu sehen, ob es wirklich gesetzt wurde. Versuchen Sie ebenfalls, abzufragen, ohne dass der Interrupt aktiviert ist, und sehen Sie, ob er gesetzt wird und ob Sie ihn löschen können. überprüfen, ob die Dokumentation korrekt ist oder nicht.
Das wäre nicht der erste Fall, den ich in Atmel-Produkten gesehen habe, wo ein "automatisch gelöschter" Interrupt nicht wirklich gelöscht zu werden scheint, wenn der Handler feuert.
@ConnorWolf: Wirklich? Erinnern Sie sich an den Controller und den Interrupt? Wir arbeiten ziemlich viel mit Atmel-Controllern und dies könnte ein potenzieller Fallstrick sein.
@Rev1.0 - Ein Beispiel, mit dem ich gerade arbeite: SAM4SD32C- Die Timer-Interrupts ( TC0_Handler, etc ...) werden beim Betreten der ISR nicht gelöscht, es sei denn, ich lese ausdrücklich TC0->TC_SR. Wenn Sie tiefer graben, liegt dies in diesem Fall daran, dass der Interrupt vom RCMatch-Bit des Vergleichsregisters ausgelöst wird und erst gelöscht wird, wenn Sie explizit lesen TC_SR. IOW, ich bin in Bezug auf die tatsächliche Ursache falsch (es war nicht direkt das ISR-Bit), aber das Endergebnis ist dasselbe: Sie müssen die ISR- Ursache manuell löschen , wenn nicht das ISR- Flag .
Vielleicht gibt es eine Errata?
Wenn Ihre ISR zu spät läuft (andere ISRs verbrauchen Zeit) und der Interrupt erneut auftritt, während Sie den Timer neu programmieren, können Sie verwirrt werden ....

Antworten (2)

Gibt es ein Szenario/einen Grund, wo das manuelle Löschen des Flags erforderlich sein kann?

Bei der ASF bin ich mir nicht sicher, aber es gibt Fälle, in denen Sie einen anstehenden Interrupt abbrechen müssen. Wenn Sie beispielsweise einen Timer (neu) konfigurieren, möchten Sie möglicherweise Interrupts deaktivieren, den Timer ändern und alle Timer-Interrupts löschen, die in der Zwischenzeit aufgetreten sind, bevor Sie Interrupts erneut aktivieren.

Wenn Sie nicht einmal eine Überlauf-ISR haben, können Sie immer noch den OVIF abfragen, um einen Überlauf zu erkennen, und das Flag zurücksetzen, um ihn für den nächsten Überlauf bereit zu machen.

Im Allgemeinen lösche ich Interrupt-Flags immer kurz vor dem Aktivieren eines bestimmten Interrupts, falls etwas das Flag in der Vergangenheit gesetzt hat. Scheint eine günstige Versicherung zu sein.

Mir ist kein Szenario bekannt, in dem Sie das Flag manuell löschen müssen, es sei denn, Sie verwenden keine Interrupts, und Sie betrachten das Flag mit einer Routine, die regelmäßig ausgeführt wird, um zu prüfen, ob das Flag gesetzt ist.