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.
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.
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
voidTIM2_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
voidTIM2_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.
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.
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.
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...