So konfigurieren Sie STM32F4s TIM1 und 8 für PWM

Ich habe Timer 4 für PWM mit folgendem Code konfiguriert und LED an den konfigurierten Pin angeschlossen. Es funktioniert.

TIM_TimeBaseInitTypeDef TIM_BaseStruct;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);    // Enable bus clock

TIM_BaseStruct.TIM_Prescaler = 0;   // Set prescaler (frequency divider)
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1;    // Set counting mode (up, down, center-aligned) to center aligned for better motor control
TIM_BaseStruct.TIM_Period = 4000; // Set timer period (timer reset/change direction value)
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);    // Initialize timer with chosen settings
TIM_Cmd(TIM4, ENABLE);  // Start timer

GPIO_InitTypeDef GPIO_InitStruct;

/* Clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);

/* Set pins */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);

TIM_OCInitTypeDef TIM_OCStruct;

TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;

TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCStruct.TIM_Pulse = 1999;
TIM_OC1Init(TIM4, &TIM_OCStruct);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

aber als ich TIM 1 konfigurierte und die LED an seinen Pin anschloss, passierte nichts (ich habe den Pin separat getestet, indem ich ihn als Ausgang umgeschaltet habe, um sicherzustellen, dass ich die LED an den richtigen Pin angeschlossen habe und sie aufleuchtete)

TIM_TimeBaseInitTypeDef TIM_BaseStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);    // Enable bus clock

TIM_BaseStruct.TIM_Prescaler = 1;   // Set prescaler (frequency divider)
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_CenterAligned1;    // Set counting mode (up, down, center-aligned) to center aligned for better motor control
TIM_BaseStruct.TIM_Period = 4000; // Set timer period (timer reset/change direction value)
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_BaseStruct);    // Initialize timer with chosen settings
TIM_Cmd(TIM1, ENABLE);  // Start timer

GPIO_InitTypeDef GPIO_InitStruct;

/* Clock for GPIOE */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1);

/* Set pins */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOE, &GPIO_InitStruct);

TIM_OCInitTypeDef TIM_OCStruct;

TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;

TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCStruct.TIM_Pulse = 1999;
TIM_OC1Init(TIM1, &TIM_OCStruct);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

Gibt es etwas anderes, was ich bei fortgeschrittenen Timern tun muss, damit sie mit pwm funktionieren? Ich habe auch Erfolg mit TIM3 und TIM12 (die Allzweck-Timer sind), aber nicht mit TIM8 (das auch ein fortgeschrittener Timer ist).

Antworten (2)

Mit Hilfe von Leuten im STM32-Forum fand ich heraus, dass mir der folgende zusätzliche Code fehlte, damit der erweiterte Timer genauso funktioniert wie der Allzweck-Timer:

TIM_BDTRInitTypeDef TIM_BDTRInitStruct;
TIM_BDTRStructInit(&TIM_BDTRInitStruct);
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStruct);
TIM_CCPreloadControl(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);

Hinweis: Kanäle müssen initialisiert werden, bevor der Code für erweiterte Funktionen aufgerufen wird. Wenn Sie danach versuchen, Kanäle zu initialisieren, kann es zu Problemen kommen (meine an Kanal 3 angeschlossene LED, die nach erweiterten Funktionen initialisiert wurde, war immer eingeschaltet und reagierte nicht auf pwm-Änderungen, seltsamerweise funktionierte Kanal 4, wurde aber auch nach erweiterten Funktionen initialisiert). ).

Dies ist eine alte Frage, aber ich habe einen allgemeinen Kommentar zu Ihrem Code, da er Fehler verursachen könnte (ich bin erst heute auf diesen Fehler gestoßen, der mich daran hindert, PWM überhaupt zu verwenden). Ich poste es als Antwort, weil ich mit meinem neuen Konto noch keine Kommentare verwenden kann.

Bei der Verwendung von Init-Strukturen empfiehlt es sich, die entsprechenden struct-Init-Funktionen aufzurufen, bevor Sie irgendetwas anderes tun, z. B. hier TIM_TimeBaseStructInit()for TIM_TimeBaseInitTypeDef, GPIO_StructInit()for GPIO_InitTypeDefund TIM_OCStructInit()for TIM_OCInitTypeDef.

Ein nicht initialisiertes Strukturelement kann unerwartetes Verhalten auslösen. In Ihrem Code haben Sie nicht alle Mitglieder von initialisiert TIM_OCStruct, was bedeutet, dass TIM_OC1Init()schmutzige Werte verwendet werden, um die Timer-Register zu initialisieren. Sie sollten alle Mitglieder einzeln anrufen TIM_OCStructInit()oder einstellen.