STM32F446RE - Timer 4 PB7 geht nicht

OP #6698209
Lesenswert?
• ▲
▼
Hallo zusamme,

ich brauche die Hilfe eines weiteren Augenpaars. Ich habe hier ein 
Nucleo64 mit einem STM32F446RE. Auf PB5 mit Timer TIM3 kann ich eine PWM 
ausgeben, auf PB7 mit TIM4 nicht.

Toggle ich PB7 über das GPIOx->ODR - Register, erhalte ich ein sauberes 
Rechtecksignal. Der MCU-Pin hängt also am richtigen Pin der Stiftleiste, 
und es ist auch keine andere Hardwarekomponente auf dem Eval-Board, die 
mein Anliegen verhindert.

Zum Testen habe ich die Initialisierung der PWM fast komplett nach vorn 
gezogen. Der Quelltext ist angehängt. Im Beitrag wird er zu sehr 
auseinandergezogen.

Hat das globale Define BUZZER_PWM den Wert buzzer_STM32F4XX_TIM3_PB5, 
bekomme ich ein schönes Rechtecksignal an PB5. Hat es dagegen den Wert 
buzzer_STM32F4XX_TIM4_PB7, ist nichts an PB7 vorhanden.

TIM3 und TIM4 sind beide an APB1 und beide an GPIOB. Bei beiden ist es 
die alternative Pin-Funktion AF2. Bei beiden ist es CH2 (nicht, dass das 
wichtig wäre - es werden eh alle beschrieben).

Und jetzt bin ich an dem Punkt angekommen, an dem zwei Augen nicht mehr 
ausreichen. Siehst Du mehr?

Nachtrag: Ich habe die Ursache gefunden, verstehe sie aber nicht.

In Headern ist definiert:
1
    #define BUZZER_PWM   buzzer_STM32F4XX_TIM4_PB7
2

3
    /** Summer: Auswahl Ports und Pins */
4
    enum buzzertype_e
5
    {
6
        buzzer_STM32F4XX_TIM3_PB5,
7
        buzzer_STM32F4XX_TIM4_PB7,
8
    };
(In welcher Reihenfolge die beiden "includiert" werden, muss ich noch 
schauen.)

In der Auswahl
1
  #if( BUZZER_PWM == buzzer_STM32F4XX_TIM3_PB5 )
2
    [...]
3
    TIMx = TIM3;
4
    [...]
5

6
  #elif( BUZZER_PWM == buzzer_STM32F4XX_TIM4_PB7 )
7
    [...]
8
    TIMx = TIM4;
9
    [...]
10
  #else
11
    #error "Invalid config for buzzer pwm"
12
  #endif
wird trotzdem TIMx die Adresse von TIM3 zugeordnet - also der falsche 
Zweig durchlaufen.

Ändere ich die Präprozessorweiche in ein switch-case, funktioniert es 
wie erwartet.
Angehängte Dateien:
Beitrag #6700844 wurde von einem Moderator gelöscht.
OP #6700855
Lesenswert?
• ▲
▼
Man sieht bei den unteren Funktionen die Auswahl einer benannten 
Variante mit switch/case. Da sind enums für die Benennung erst einmal 
"natürlich".

Oben in der init()-Funktion ist switch/case so lange möglich, wie der 
Teil dazwischen für alle enum-Werte kompiliert. Für die beiden benannten 
Werte ist das kein Problem. Bestünde das enum aus einem Wert mehr, z.B.
1
    enum buzzertype_e
2
    {
3
        buzzer_STM32F10x_TIM3_PB5,
4
        buzzer_STM32F4XX_TIM3_PB5,
5
        buzzer_STM32F4XX_TIM4_PB7,
6
    };
müsste ich innerhalb jedes "case" noch zusätzlich im Präprozessor die 
MCU abfragen.

Deswegen behaupte ich: Skurril ist es nicht. Es funktioniert nur nicht 
(und die Ursache ist die interne Funktionsweise des Compilers). Würde es 
funktionieren, wäre es sinnvoll.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.