25-PWM-Library (STM32F4)

Um die PWM-Funktionen vom STM32F4 benutzen zu können, habe ich diese Library(s) geschrieben.

Der STM32F4 hat sehr viele Timer (14) und fast alle haben eine PWM funktion. Um den Aufwand etwas einzugrenzen hab ich mich für die 4 “General Purpose Timer” (TIM2, TIM3, TIM4, TIM5) entschieden, weil diese pro Timer 4 Kanäle besitzen.
Ich habe für jeden Timer eine eigene Library geschrieben, die bis auf die Namen der Funktionen und Variabeln gleich sind.

Somit kann man also, wenn man alle 4 Librarys benutzt und je 4 Kanäle aktiviert, maximal 16 PWMs realisieren.

Die Anzahl und Namen der PWMs die benutzt werden sollen, müßen im H-File deklariert und im C-File den entsprechenden Port-Pins zugeordnet werden.
(bei den Beispielen hab ich immer nur zwei PWMs pro Timer aktiviert)

Im H-File wird auch pro Timer die gewünschte Auflösung und die PWM-Frequenz eingestellt. Diese gilt dann für alle 4 Kanäle die mit diesem Timer betrieben werden.
Auch wird im H-File die Polarität vom PWM fesgelegt.

Beispielbild :

pwm

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO, TIM
Benutzte Librarys : keine

Enumerationen (für PWM mit TIM2) :

1
2
3
4
typedef enum {
  PWM_T2_PB11 = 0,  // PWM per TIM2 an PB11
  PWM_T2_PA2  = 1   // PWM per TIM2 an PA2
}PWM_TIM2_NAME_t;

Funktionen (für PWM mit TIM2) :

1
2
void UB_PWM_TIM2_Init(void);                                 // um den PWM mit TIM2 zu initialisieren
void UB_PWM_TIM2_SetPWM(PWM_TIM2_NAME_t pwm, uint16_t wert); // zum einstellen eines PWM wertes

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//--------------------------------------------------------------
// File     : main.c
// Datum    : 26.03.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.0
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der PWM-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_pwm_tim4.h"
#include "stm32_ub_adc1_single.h"
 
int main(void)
{
  uint16_t ad_wert;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init vom ADC
  UB_ADC1_SINGLE_Init();
 
  // Init vom PWM mit Timer4
  // Settings vom H-File :
  //   Auflösung = 8bit (0...255)
  //   Frequenz = 1kHz
  //   Kanal1 an PD12
  //   Kanal2 an PD14
  UB_PWM_TIM4_Init();
 
  // PD12 auf 25% einstellen
  UB_PWM_TIM4_SetPWM(PWM_T4_PD12,64);
 
  // PD14 auf 50% einstellen
  UB_PWM_TIM4_SetPWM(PWM_T4_PD14,128);
 
  while(1)
  {
    // AD-Wert an PA3 lesen
    ad_wert=UB_ADC1_SINGLE_Read_MW(ADC_PA3);
    // von 12bit in 8bit umwandeln
    ad_wert=(ad_wert>>4);
    // als PWM Wert an PD12 ausgeben;
    UB_PWM_TIM4_SetPWM(PWM_T4_PD12,ad_wert);
  }
}

Hier die Library zum Download :

ub_stm32f4_pwm_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_25_PWM

16 Antworten auf 25-PWM-Library (STM32F4)

  1. Robert sagt:

    Hallo,
    vielen Dank für diese und alle anderen Libs! Einige benutze ich schon erfolgreich. Bei dieser habe ich jedoch zum ersten Mal ein Problem:

    Die PWM an PD12 hat immer 25%, egal welchen Wert ich einstelle:
    // PD12 auf 25% einstellen
    UB_PWM_TIM4_SetPWM(PWM_T4_PD12,64);

    In der nächsten Zeile für PD14 funktioniert’s perfekt!

    Außerdem bekomme ich es nicht hin, die 2 weiteren PWMs zu aktivieren. Ich habe im h-File eingetragen:
    typedef enum
    {
    PWM_T4_PD12 = 0, // PWM per TIM4 an PD12
    PWM_T4_PD14 = 1, // PWM per TIM4 an PD14
    PWM_T4_PD13 = 2, // PWM per TIM4 an PD13
    PWM_T4_PD15 = 3 // PWM per TIM4 an PD15
    }PWM_TIM4_NAME_t;

    #define PWM_TIM4_ANZ 4 // Anzahl von PWM_TIM4_NAME_t

    Aber PD13 und PD15 bleiben tot. Was muss ich noch tun?

    Nochmals vielen Dank!

    • admin_ub sagt:

      das H-File hast du richtig geändert. Aber im C-File müssen die beiden neuen PWMs auch noch eingetragen werden.

      PWM_TIM4_t PWM_TIM4[] = {
        // Name     ,Channel, PORT , PIN       , CLOCK               , Source         , Init
        {PWM_T4_PD12,1      ,GPIOD ,GPIO_Pin_12,RCC_AHB1Periph_GPIOD ,GPIO_PinSource12,  64},
        {PWM_T4_PD14,3      ,GPIOD ,GPIO_Pin_14,RCC_AHB1Periph_GPIOD ,GPIO_PinSource14,  128},
        {PWM_T4_PD13,2      ,GPIOD ,GPIO_Pin_13,RCC_AHB1Periph_GPIOD ,GPIO_PinSource13,  64},
        {PWM_T4_PD15,4      ,GPIOD ,GPIO_Pin_15,RCC_AHB1Periph_GPIOD ,GPIO_PinSource15,  128},
      };
      

      probier mal aus ob damit der Fehler weg ist und alle 4 PWMs funktionieren.

  2. Robert sagt:

    Super, danke!
    Jetzt kommt aus allen 4 Pins etwas raus :)

    Allerdings ist die PWM auf PD12 noch immer nicht einstellbar, sondern fest bei 25%.
    Die anderen 3 lassen sich prima einstellen.

    • admin_ub sagt:

      du benutzt aber nicht das Beispielprogramm von hier oder ? …weil da wird PD12 in der while ständig mit einem Wert beschrieben !!

  3. Robert sagt:

    Aaaaah!
    Wer guckt denn schon in die while?

    Oh man, danke!

    • kann sein, dass du 4 PWMs für einen Quadcopter brauchst?
      Wenn ja, wie ist der Stand bei Dir?

  4. Cortex-Einsteiger sagt:

    zur Info:
    Wenn mann mehrere PWM-Timer gleichzeitig benutzen möchte, meckert der Compiler.
    Die internen Funktionen werden in jeden File neu erstellt: P_PWM_InitIO(); P_PWM_InitTIM();

    Ich habe die Funkionen jeweils mit einem Index des Timers versehen, so dass kein Name mehr doppelt vorkommt, es scheint zu laufen.

  5. Joerg B sagt:

    Muss ich etwas besonderes beachten wenn ich Pf9 /Tim14 Channel1 benutzen will?

  6. Joerg B sagt:

    Ok funktioniert Problemlos.
    Wichtig ist bei der Nutzung mehrerer Timer die Funktionsnamen anzupassen.

  7. Hallo admin_ub,

    ich wollte zwischen Demo_84_SPI_LIS3DSH und Demo_25_PWM ein Kombination erstellen. Ich habe dir “neueren” Header-Dateien eingepflegt aber er wollte dann nicht mehr compilieren.
    Mein Ziel ist je nach Neigung des Sensors den Tastverhältnis der unterschiedlichen 4PWM zu ändern.

    Auf eine Antwort freue ich mich.
    Danke!

    • admin_ub sagt:

      mit der Fehlermeldung “er wollte dann nicht mehr compilieren” kann ich nichts anfangen.
      1. Neues “leeres” projekt anlegen
      2. Files von LIS3DSH, SPI1, PWM hinzufügen.
      3. Compiler darf keinen Fehler melden
      4. Erst jetzt eigenen Code hinzufügen

  8. Jens sagt:

    Hallo,

    wie bekomme ich (bei PE10) z.B. den “TIM1_CH_2N” zum laufen?
    Der “TIM1_CH_2″ (PE11) funktioniert einwandfrei.

    Ich möchte quasi 2 PWM-Signale erzeugen, die um 180° versetzt sind, um ein Encoder-Signal zu simulieren.

    Vielen Dank für die baldige Antwort :)
    Gruß Jens

    • admin_ub sagt:

      den Pin in der PWM-Struktur eintragen, damit er als GPIO konfiguriert wird

      in der OCInitStructure müssen dann noch zwei Werte gesetzt werden :

      TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
      TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

      polarität entweder “TIM_OCNPolarity_High” oder “TIM_OCNPolarity_Low”
      das “TIM_CtrlPWMOutputs(TIM1, ENABLE);” darf bei Timer-1
      auch nicht vergessen werden.

      Hinweis : Encoder-Signale sind nicht invertiert sondern
      90° Phasenverschoben

      • Jens sagt:

        vielen Dank für die schnelle Antwort.

        Ja das meinte ich, die Phasenverschiebung. Habe mich einfach bescheuert ausgedrückt.

        Ist deine Lösung für die Phasenverschiebung?

        Gruß Jens

        • admin_ub sagt:

          mach es anders. Nimm das original Beispiel von hier mit Timer-2 per CH3 und CH4. Dann ändere bei allen Kanälen den Timer-Mode von “PWM” in “Toggle” also die Zeilen :

          TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;

          damit ergeben sich zwei Rechtecksignale,
          deren Tastverhältnis immer 50/50 ist aber
          die Phasenlage untereinander lässt sich über die
          Pulswerte einstellen.
          Stell CH4 auf einen Pulswert von 1 und CH3
          auf einen Pulswert von 128 dann sind sie um 90°
          versetzt.

          • Jens sagt:

            Hallo,

            Danke!
            Ich habe es mit der PWM nun doch zum Laufen gebracht.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert