Hallo, ich habe ein Problem mit einem STM32F303RE. In meiner Software benutze u.a. Timer 4 und möchte nach einer gewissen Zeit einen Capture Compare Interrupt auslösen. Das funktioniert auch prima. Wenn ich allerdings den Wert des CC-Register so wähle, dass er größer als der Wert des Auto Reload Register ist, so sollte meiner Meinung nach kein Interrupt ausgelöst werden. Das Gegenteil ist aber der Fall. Timer 4 habe ich folgendermaßen konfiguriert: Interne Clock - 64MHz PSC: 3199 ARR: 19999 CC1: 20001 Um der Sache weiter auf den Grund zu gehen und ein Problem mit meiner selbst geschriebenen Software auszuschließen, habe ich mit Hilfe von STM32CubeMx ein weiteres Programm erstellt, die auf einem STM32F303-Nucleo Board läuft. Es wird lediglich Timer 4 konfiguriert und benutzt. Hier kann ich das gleiche beobachten. Der Interrupt wird ausgelöst, obwohl CC1 > ARR. Nehme ich statt Timer 4 den Timer 15, ist das Ergebnis das gleiche. Im Reference Manual des Microcontrollers steht "...when a match is found between the capture/compare register and the counter...". Da der Counter ja nur bis ARR zählt und somit nie den Wert von CC1 erreicht, sollte auch kein Interrupt ausgelöst werden. Hat jemand ähnliche Erfahrungen oder habe ich etwas falsch verstanden? Grüße Jörg
Zwischenstand: Gleiches Verhalten bei: STM32L053 Discovery Board STM32F407 Discovery Board STM8L Discovery Board Ich teste jetzt noch einen Atmel Atmega168
Jörg schrieb: > Hat jemand ähnliche Erfahrungen oder habe ich etwas falsch verstanden? Wahrscheinlich das ... Hast du an den Counter-Wrap-Around gedacht? Der bleibt am Maximal-Wert meines Wissens nicht stehen sondern fängt bei 0 wieder an und dann ist er wieder kleiner CC und matcht irgendwann.
> Timer 4 habe ich folgendermaßen konfiguriert: > Interne Clock - 64MHz > PSC: 3199 > ARR: 19999 > CC1: 20001 Das weiß ich, dass der Counter auf 0 zurückgesetzt wird. Bei meinem Problem zählt er ja nur bis 19999 (ARR) und beginnt dann wieder bei 0. Der Wert des CC1 Registers wird ja nie erreicht. Und daher sollte doch auch der CC1 Interrupt nicht ausgelöst werden?!?
Jörg schrieb: > Das weiß ich, dass der Counter auf 0 zurückgesetzt wird. Bei meinem > Problem zählt er ja nur bis 19999 (ARR) und beginnt dann wieder bei 0. > Der Wert des CC1 Registers wird ja nie erreicht. Und daher sollte doch > auch der CC1 Interrupt nicht ausgelöst werden?!? Poste doch mal Code - wenn man selbst Prosa-Texte verfasst, fließen unweigerlich Informationen ein, mit denen man sich selbst gerne bestätigt - auch wenn sie womöglich falsch sind.
Das ist die Software für das STM32F303 Nucleo Board. Erstellt mit STM32CubeMX (um auszuschließen, dass es an meiner eigenen Software hängt)
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; Kenn mich hier wenig aus. Kann sein dass der Timer doch einfach weiterläuft? Wie ist es mit Preload auf 0? Kannst das mal versuchen?
"Preload Disabled" bedeutet, dass ein direktes Schreiben in das ARR Register möglich ist. Der Wert wird sofort geändert. Wenn man Preload enabled, wird der Wert erst in ein Preload Register geschrieben und dann beim nächsten Update-Event übernommen. Da ich das ARR Register nur einmal setze, sollte es daher keinen Unterschied machen.
Jörg schrieb: > Das ist die Software für das STM32F303 Nucleo Board. Erstellt mit > STM32CubeMX (um auszuschließen, dass es an meiner eigenen Software > hängt) Hmm,
1 | uint32_t Period; /*!< Specifies the period value to be loaded into the active |
2 | Auto-Reload Register at the next update event.
|
3 | This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */
|
Das macht was anderes, als das, was du dachtest, oder?
:
Bearbeitet durch User
Nein. Das CNT-Register zählt nur bis zum Wert des ARR-Registers, hier als Period definiert. Kann man sich im Debugger im Register-View ansehen.
Kommt Dein Interrupt nur einmal oder öfter? Ich habe bei STM32 auch schonmal beobachtet, dass eine Interrupt nach Initialisierung bereits gesetzt ist. Warum? Siehe. UIF (update interrupt flag). Workaround nach dem setzen der Register und vor dem Starten des Timers:
1 | // Ohne die nächste Zeile ist die erste Wartezeit nach dem Reset null
|
2 | __HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_UPDATE); |
Wo ist eigentlich das Problem? Was soll es bringen, CCx auf was größeres als ARR zu setzen? Weil es dafür keinen sinnvollen Use Case gibt, macht der Timer da vermutlich Unfug. Wenn du das Compare Event abschalten willst, nutze DIER, CCMR und CCER.
Ich erzeuge mit dem Timer eine PWM. Wenn ich einen Duty-Cycle von 100% benötige, soll der Interrupt nicht ausgeführt. Als Workaround schalte ich im Moment den Interrupt einfach bei 100% Duty Cycle ab. Trotzdem würde mich interessieren, warum sich der Timer so verhält.
Jörg schrieb: > Als Workaround schalte ich im Moment den Interrupt einfach bei 100% Duty > Cycle ab. Ich würde sagen das ist kein Workaround sondern die korrekte Lösung.
Jörg schrieb: > Nein. Das CNT-Register zählt nur bis zum Wert des ARR-Registers, > hier > als Period definiert. > Kann man sich im Debugger im Register-View ansehen. Hmm ja stimmt, laut Datenblatt ist es so, wie du geschrieben hast ... An deinem Code sehe ich auch nichts, was nicht stimmen würde. Seltsam ... Welchen Zählerwert hat der Timer denn, wenn der Interrupt auftritt?
Jörg schrieb: > Ich erzeuge mit dem Timer eine PWM. Wenn ich einen Duty-Cycle von 100% > benötige, soll der Interrupt nicht ausgeführt. Aha ... 100% und 0% haben glaub ich Sonderfunktionen ... Das eine ist ein single-Pulse oder sowas.
Hmm ... > In case of a PWM with a 100% duty cycle (if CCRx>ARR), OCxREF is > enabled again at the next counter overflow. Das ist dein Problem, oder?
Im Reference Manual ist das Verhalten sogar dokumentiert. Im RefMan vom STM32F103 (hatte ich gerade zur Hand) sieht man im Diagramm auf S. 318, dass das Interrupt Flag "IF" immer aktiv ist, wenn CCRx>ARR oder CCRx=0. Vielen Dank fürs Diskutieren und Rätselraten lassen :-)
Mampf F. schrieb: > Seltsam ... Welchen Zählerwert hat der Timer denn, wenn der Interrupt > auftritt? Der Counter steht bei "0". Das CC1IF im SR ist gesetzt. Laut Reference Manual: "This flag is set by hardware when the counter matches the compare value..." matches heißt für mich CNT == CCR1
Dr. Sommer schrieb: > Im Reference Manual ist das Verhalten sogar dokumentiert. Im > RefMan vom > STM32F103 (hatte ich gerade zur Hand) sieht man im Diagramm auf S. 318, > dass das Interrupt Flag "IF" immer aktiv ist, wenn CCRx>ARR oder > CCRx=0. Vielen Dank fürs Diskutieren und Rätselraten lassen :-) Wo genau steht das? Das habe ich gesucht... Im Übrigen benutzte ich den STM32F 3 03
Dr. Sommer schrieb: > Im Reference Manual ist das Verhalten sogar dokumentiert. Im RefMan vom > STM32F103 (hatte ich gerade zur Hand) sieht man im Diagramm auf S. 318, > dass das Interrupt Flag "IF" immer aktiv ist, wenn CCRx>ARR oder > CCRx=0. Vielen Dank fürs Diskutieren und Rätselraten lassen :-) Refernce Manual DocID 13902 Rev 15 ?
Hier als Screenshot aus dem RefMan, diesmal richtig für den STM32F303RE und TIM4. Seite 626.
Ich hab's gefunden :) Im Reference Manual des F303 (DocID 22558 Rev 8) steht bei Timer 15 genau das, was Dr. Sommer beim F103 gefunden hat. Nur leider nicht bei Timer 4... Danke für's Helfen :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.