Ich sehe hier verschiedene konzeptionelle Fehler.
Zu aller vorderst: Es gibt zwei grundlegende Möglichkeiten, ein PWM
signal zu erzeugen. In Hardware, für das das CCR-Register benutzt wird,
oder in Software, indem man den aktuellen Zählerwert des Timers in
Software vergleicht. Du hast eine Mischung implementiert, und verwendest
daher die Hardware nicht wie vorgesehen.
Desweiteren:
Ein Interrupt flag setzt sich nur in einigen wenigen Fällen selbst
zurück, der Timer gehört definitiv nicht dazu. Um das Flag zurück zu
setzen, musst du das entsprechende bit in software zurücksetzen.
Und ja, du bist mit Interrupt Flags auf dem Holzweg, das ist nicht
hilfreich bei der grundlegenden Implementierung eines PWM.
Es ist ungewöhnlich, dass du den Timer erst einschaltest (TIM15->CR1 |=
(1<<0);) und danach erst initialisierst. Das mag vieleicht
funktionieren, kann aber zu allen möglichen Fehlverhalten führen.
Initialisiere erst, und aktiviere erst ganz zum schluss den counter!
Willst du einen PWM in Software realisieren, so könnte das in etwa so
aussehen:
1 | while(1)
|
2 | {
|
3 | if(TIM15->CNT < 500) // Check current count value
|
4 | {
|
5 | GPIOC->ODR |= (1<<7); //Turn GPIOC Pin 7 ON or assert high
|
6 | }else{
|
7 | GPIOC->ODR &= ~(1<<7);
|
8 | }
|
9 | }
|
Das ist aber nicht die elegante methode. Verwende besser die gegebene
Timer Hardware. Diese wird im Unterkapitel "PWM mode" des Timers deiner
Wahl im Reference Manual beschrieben. Zusätzlich musst du dann noch die
entsprechenden Pins deines Controllers auf "Alternate Function"
konfigurieren. Wie das funktioniert, erfährst du im Kapitel
"General-purpose I/Os" des Reference Manuals. Welche Pins du für den
Timer verwenden kannst, kannst du dem "Device Summary" entnehmen.
Ich hoffe, das war so weit hilfreich.
Stelle gerne weitere Fragen, wenn irgendwas nicht klar ist!
~Lil-B