Hallo, Ich möchte PA11 eines STM32G031J6M6 mit 50 kHz blinken lassen, bzw. ein entsprechendes Rechtecksignal am Pin 5 generieren. Dafür habe ich TIM2 so konfiguriert, dass er alle 10 us überläuft, was eine ISR ("TIM2_IRQHandler") aufruft, welche den Zustand von PA11 umkehrt. Der angehängte Code funktioniert soweit. Das heisst, der Timer tut, was er soll und das Toggeln funktioniert ebenfalls. Nur crasht das Program leider bei einem Überlauf von TIM2, statt meine ISR aufzurufen. Vielen Dank schon einmal.
In der IRQ am Ende fehlt noch ein NVIC_ClearPendingIRQ(nbr). Sonst gibts Dauerfeuer vom NVIC.
Der Status wird automatisch von "pending" auf "active" gesetzt, sobald die ISR aufgerufen wird. Es ist also nicht nötig, den Status per Software zu "clearen". Trotzdem habe ich's mal eingefügt und ausprobiert: Macht keinen Unterschied.
Stand hier mal irgendwo im Forum - erst den Timer IRQ löschen, dann an den Ports rumfummeln.
Könnte man so machen, muss man aber - jedenfalls in diesem Falle - nicht so machen. Trotzdem habe ich auch das ausprobiert: Macht keinen Unterschied.
Keine Ahnung, ob folgendes Schuld ist. (Ich habe ehrlich gesagt deine Frag enicht verstanden. Du schreibst, dass die LED toggelt, aber die ISR nicht aufgerufen wird... Dabei wird doch in der ISR getoggelt)... Egal: Mach mal aus
1 | void TIM2_IRQHandler(void) { |
2 | |
3 | //Toggle PA11 (pin 5).
|
4 | |
5 | GPIOA->ODR ^= (0x1u << 11); |
6 | |
7 | //Clear TIM2 update interrupt flag.
|
8 | |
9 | TIM2->SR &= ~TIM_SR_UIF; |
10 | |
11 | }
|
folgenden Code:
1 | void TIM2_IRQHandler(void) { |
2 | |
3 | TIM2->SR &= ~TIM_SR_UIF; |
4 | __DSB(); // sollte in der cmsis header Datei definiert sein... |
5 | |
6 | //Toggle PA11 (pin 5).
|
7 | |
8 | GPIOA->ODR ^= (0x1u << 11); |
9 | }
|
Manchmal gibt es das Phänomen, dass man das Flag löscht und die CPU aus der ISR springt, aber der "Löschvorgang" des Interrupt Flags im Peripheral noch nicht durch den Bus durch ist. Dann wird gleich nochmal ausgelöst. Das DSB (Assemblerbefehl für eine "Data synchronization barrier") Sollte das verhindern. Passt aber eigentlich nicht ganz zu deinem Fehlerbild (, das ich zugegebenermaßen nicht genau verstanden habe).
@bambel2 & mschoeldgen: Dieses Fehlerbild tritt bei Cortex-M0+ wohl prinzipiell nicht auf: https://developer.arm.com/documentation/ka003795/latest Jedenfalls kämpfe ich nicht mit diesem Problem. Du hast in der Tat mein Fehlerbild nicht ganz verstanden: Die LED toggelt mit dem im Ursprungs-Post angefügten Code nie und die ISR wird nie aufgerufen - wohl funktioniert der Timer aber einwandfrei. Ich habe das Toggeln, bzw. die Funktion der ISR aber noch separat getestet: Ich habe im selben Code Interrupts global nicht "geenabled" (__disable_irq()) und dann in der while-Schlaufe in main() das Überlaufflag des TIM2 gepolt. Wenn ich da bei jedem Flag die ISR aufrufe, bekomme ich die 50 kHz an Pin 5.
Master-Jimmy schrieb: > Du hast in der Tat mein > Fehlerbild nicht ganz verstanden: > Die LED toggelt mit dem im Ursprungs-Post angefügten Code nie Sagen wir mal lieber, du hast es nicht verstanden, die Fehlerbeschreibung richtig zu machen. Denn du schreibst ja im ersten Posting: Master-Jimmy schrieb: > Das heisst, der Timer tut, was > er soll und das Toggeln funktioniert ebenfalls. Also was denn nun? Schau auch bitte mal, ob bei der G-Serie Clocks für NVIC aktiviert werden müssen und ob der NVIC ohne Konfiguration glücklich ist.
Matthias S. schrieb: > Also was denn nun? Schau auch bitte mal, ob bei der G-Serie Clocks für > NVIC aktiviert werden müssen und ob der NVIC ohne Konfiguration > glücklich ist. Clocks müssen da keine aktiviert werden und konfiguriert werden muss per se eigentlich auch nichts - es gibt Default-Prioritäten: -> Reference Manual: https://www.st.com/resource/en/reference_manual/rm0444-stm32g0x1-advanced-armbased-32bit-mcus-stmicroelectronics.pdf#page=314&zoom=100,89,116 -> Programming Manual: https://www.st.com/resource/en/programming_manual/pm0223-cortexm0-programming-manual-for-stm32l0-stm32g0-stm32wl-and-stm32wb-series-stmicroelectronics.pdf#page=82&zoom=100,89,117 Allerdings lässt sich mein Problem tatsächlich erst einmal lösen, wenn ich "meinem" Interrupt die Priorität 0 zuweise. "Mein" Interrupt, welcher per default die Prio. 22 haben müsste, wird also offenbar von irgend einem anderen Interrupt verdeckt. Jetzt muss ich einfach noch herausfinden, was da dazwischen feuert. VIELEND DANK MSCHOELDGEN. DAS BEANTWORTET FÜR MICH DIE FRAGE HINREICHEND.
Die Zeile die den Unterschied macht, ist Zeile 38.
Master-Jimmy schrieb: > die Priorität 0 zuweise. Wenn du das schrittweise höher drehst, kannst du den Störer herausfinden. Aber eigentlich gibt es nur SysTick, wenn man nichts weiter aktiviert.
Jetzt ist es ein .cpp, ist der TIM2_Handler als extern "C" deklariert? Stimmt der Name mit der Definition in der Vektortabelle überein?
Johannes S. schrieb: > Jetzt ist es ein .cpp, ist der TIM2_Handler als extern "C" > deklariert? > Stimmt der Name mit der Definition in der Vektortabelle überein? Ich habe da offensichtlich beim Posten verschiedene Versionen durcheinander gebracht. Auf meiner Seite hatte ich aber diese "Problematik" stets im Griff. Danke trotzdem für den Hinweis. Matthias S. schrieb: > Master-Jimmy schrieb: >> die Priorität 0 zuweise. > > Wenn du das schrittweise höher drehst, kannst du den Störer > herausfinden. Aber eigentlich gibt es nur SysTick, wenn man nichts > weiter aktiviert. Du hast eigentlich recht. Allerdings kann ich nun den Fehler gar nicht mehr reproduzieren. Wenn ich nun also die Zeile, wo die Priorität für TIM2_IRQn gesetzt wird, wieder auskommentiere funktioniert der Code trotzdem. Wie auch immer... Ich werde in Zukunft wohl einfach stets explizit Prioritäten setzen, selbst wenn dies nicht nötig sein sollte.
in meinem Timer Code habe ich noch ein Interrupt Flag löschen vor dem Enable IRQ drin, könnte auch nötig sein.
Johannes S. schrieb: > in meinem Timer Code habe ich noch ein Interrupt Flag löschen vor > dem > Enable IRQ drin, könnte auch nötig sein. Das sollte nicht nötig sein - von wo sollte das Pending Flag den kommen?? Hatte ich aber die letzten Tag auch bereits ausprobiert. Hatte nichts gebracht.
Es könnte im Prinzip an der HW liegen/gelegen haben... Die entsprechenden Interrupts hätten ja ebenfalls höhere Prioritäten. Ich habe ausserdem das ursprüngliche Board (STM32G0316-DISCO) geschrottet. Mit dem Ersatzteil hatte ich das Problem noch gar nicht versucht zu reproduzieren. Ich war bisher auch nie auf die Idee gekommen, dass die HW die Problemquelle sein könnte. Ist ja auch ein gekauftes und getestetes (nehme ich an) Teil...
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.