COMP2 zum Auslösen des One-Pulse-Modus auf STM32L1

Ich versuche, den Ausgang von COMP2 zu verwenden, um den One-Pulse-Modus eines Timers (in meinem Beispiel TIM4, aber es ist ziemlich flexibel, wenn er zu einem anderen Timer wechseln muss) der STM32L1-Serie auszulösen.

Im Referenzhandbuch verwendet die Erklärung für den One-Pulse-Modus TI2FP2 als Timer-Trigger, der mit Input Capture auf Kanal 2 des Timers verknüpft ist, jedoch kann der Ausgang des Komparators nur auf Input Capture auf Kanal 4 umgeleitet werden (außer TIM10, aber es hat keinen zweiten Kanal, um die PWM auszugeben ...) oder OCREF Clear.

Ich habe versucht, die COMP2-Ausgabe umzuleiten auf:

  • „OCxREF Clear“ von TIM4,
  • das Input Capture 4 von TIM4,
  • Input Capture 4 von TIM3 und Verwendung von ITR2 als TIM4-Trigger (ITR2 ist TIM3, wenn es auf TIM4 verwendet wird)

aber keine dieser Optionen funktionierte.

Sollte eine dieser Konfigurationen funktioniert haben und ich sie einfach nicht richtig eingerichtet haben?

Soll ich es anders machen?

Gibt es keine Möglichkeit, die beiden direkt zu verbinden und ich sollte zum Beispiel den One-Pulse-Modus vom COMP2-Interrupt starten?

Antworten (1)

Beim Betrachten des Blockdiagramms der Timer konnte ich auch keine direkte Methode finden, es gehen anscheinend keine Signale von CH4 zur Triggereinheit.

Wenn Sie Interrupts vermeiden möchten und einen geeigneten freien DMA-Kanal haben, können Sie diesen verwenden, um einen anderen Timer zu starten. TIM2_CH4Sie können or verwenden TIM3_CH4(im Beispiel verwende ich TIM3), aber es gibt keinen DMA-Kanal für TIM4_CH4. Sie können sich an TIM4jeden anderen Timer als Ziel halten oder ihn verwenden.

  • Richten Sie TIM4den One-Pulse-Modus ein, aber starten Sie ihn noch nicht. Finden Sie heraus, welcher Wert in gehen würde TIM4->CR1, und speichern Sie ihn in einer Speichervariablen, zB volatile uint8_t tim4_cr1_start = TIM_CR1_OPM|TIM_CR1_CEN;für den einfachsten Fall.
  • Einrichten DMA1_Channel3, Speicheradresse ist &tim4_cr1_startvon oben, Peripherieadresse ist &TIM4->CR1, Übertragungslänge ist 1. Verwenden Sie den 8-Bit-Modus, aktivieren Sie den Zirkularmodus.
  • Stellen Sie TIM3_CH4die Eingangserfassung ein, wählen Sie die Polarität usw. in TIM3_CCERund aus TIM3_CCMR2.
  • Aktivieren CC4DE, erfassen/vergleichen Sie 4 DMA-Anforderungen in TIM3->DIER.
  • Starten TIM3.
  • Leiten Sie die COMP2-Ausgabe um TIM3_CH4(Sie könnten TIM4_CH4` verwenden TIM2_CH4' too, but there is no DMA channel for).

Nun würde ein Komparatorereignis eine Erfassung auf auslösen TIM3_CH4, was DMA anweisen würde, einen geeigneten Wert auf zu schreiben TIM4->CR1. Da der DMA auf den Zirkularmodus eingestellt ist, würde er denselben Wert bei TIM4->CR1jedem nachfolgenden Erfassungsereignis kopieren.

Vielen Dank für die Erklärung, ich habe das DMA noch nie wirklich benutzt, also ist es definitiv eine gute Gelegenheit, um zu lernen, wie man es benutzt! Wissen Sie, wie diese Lösung im Vergleich zur Verwendung von Interrupts in Bezug auf die Verzögerung zwischen der Änderung des COMP2-Ausgangs und dem Ein-Impuls-Modus, der am Ausgangspin beginnt, wäre?
@BenoîtVernier Der Interrupt-Eintrag in einem Cortex-M3 dauert mindestens 12 Zyklen, dann würde eine minimale Handler-Implementierung mindestens weitere 5 Zyklen dauern (1 für MOVS, 2 für LDRund 2 für STR). Es ist ein theoretisches Minimum, ich würde sagen, 20-25 Zyklen sind realistisch. Ich weiß nicht wirklich etwas über DMA-Latenzen, ich würde 3 oder 4 Zyklen schätzen, und ich wäre ziemlich überrascht, wenn es mehr als 5 dauern würde. Dann braucht der Timer in beiden Fällen vielleicht weitere 2 Zyklen, um zu starten.
@BenoîtVernier Tatsächlich kann ein Interrupt-Eintrag schneller sein, wenn ein anderer Interrupt-Handler genau im richtigen Moment beendet wird ( siehe Tail Chaining ). Der Punkt ist, dass die Interrupt-Latenz auf +/- 6 Zyklen unsicher sein kann, die DMA-Verzögerung sollte konstant sein, wenn Sie diesem Kanal die höchste Prioritätsstufe geben.