Forum: Mikrocontroller und Digitale Elektronik stm32f4 PWM mit timer 2 Chanel 4 an PB11


von Ma B. (drumstick)


Lesenswert?

Hallo

Ich verwende einen STM32F407.

Jetzt wollte ich ein PWM Signal mittels Timer 2 Channel 4 auf den 
Ausgang von Port B Pin 11 geben. Ich habe im Forum Beiträge gefunden und 
mit meinem Code Verglichen. Funktioniert aber nicht. Ich setze die 
StdLib ein.

Port/Pin Conf:
1
GPIO_InitTypeDef GPIO_InitStructure;
2
  
3
    
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
5
6
  
7
// Configure PB.11 (TIM2 Channel4) as PWM Output --------------
8
  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11;
9
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
11
  GPIO_Init(GPIOB, &GPIO_InitStructure);
12
  
13
14
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2);

Timer Conf:
1
TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
2
  TIM_OCInitTypeDef          TIM_TimeOutputModeStructure;
3
  RCC_ClocksTypeDef         RCC_ClocksStatus;
4
  
5
  
6
  /* Time base configuration */
7
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
8
  TIM_TimeBaseStructure.TIM_Period         = 20000;
9
  TIM_TimeBaseStructure.TIM_Prescaler     = ((RCC_ClocksStatus.SYSCLK_Frequency / 2) / 1000000) -1;
10
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
11
  TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;
12
    
13
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
14
  
15
  
16
  TIM_ARRPreloadConfig(TIM2, ENABLE);
17
  
18
  {
19
    TIM_OCInitTypeDef    TIM_OCInitStruct;      
20
    TIM_OCStructInit     (&TIM_OCInitStruct);
21
    
22
    TIM_OCInitStruct.TIM_OCIdleState   = TIM_OCIdleState_Reset;
23
    TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCIdleState_Set;
24
    TIM_OCInitStruct.TIM_OCMode        = TIM_OCMode_PWM1;
25
    TIM_OCInitStruct.TIM_OCPolarity    = TIM_OCPolarity_High;
26
    TIM_OCInitStruct.TIM_OutputState   = TIM_OutputState_Enable;
27
    TIM_OCInitStruct.TIM_Pulse         = 1500;
28
    
29
    TIM_OC4Init(TIM2, &TIM_OCInitStruct);
30
  }
31
  
32
  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
33
  
34
  {
35
    TIM_BDTRInitTypeDef bdtr;
36
    TIM_BDTRStructInit (&bdtr);
37
    bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
38
    TIM_BDTRConfig (TIM2, &bdtr);
39
  }
40
  
41
  
42
  /* Time Output Mode configuration */
43
  TIM_OCStructInit(&TIM_TimeOutputModeStructure);
44
  TIM_TimeOutputModeStructure.TIM_OCMode       = TIM_OCMode_PWM1;
45
  TIM_TimeOutputModeStructure.TIM_OutputState = TIM_OutputState_Enable;
46
  TIM_TimeOutputModeStructure.TIM_Pulse        = 1500;
47
  TIM_TimeOutputModeStructure.TIM_OCPolarity  = TIM_OCPolarity_High;
48
  TIM_OC1Init(TIM2, &TIM_TimeOutputModeStructure);
49
      
50
  TIM_SelectOCxM(TIM2, TIM_Channel_4, TIM_OCMode_PWM1);
51
    
52
  TIM_SetAutoreload(TIM2, 300);
53
  
54
  TIM2->EGR |= (1 << TIM_EGR_UG);
55
  
56
  /* TIM enable counter */
57
  TIM_Cmd(TIM2, ENABLE);


An Port B Pin 11 tut sich gar nichts!

Ich muss ja nach der Init nichts mehr verändern?

Mit
1
TIM_SetCompare4 (TIM2, 250);
 kann man den duty cycle verändern.


vielen Dank schon mal!
Grüsse

MC

von Thomas W. (ratos)


Lesenswert?

Clock für den Timer ist an?

von Felix G. (felixg)


Lesenswert?

Wenn mich nicht alles täuscht, hast du für den Timer die Clock 
(RCC_AHB1PeriphClockCmd) noch nicht eingeschalten.

von Ma B. (drumstick)


Lesenswert?

Hallo,

Ja!
1
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

Wenn ich debuge dann sehe im Peripheral Register des Timers 2, dass der 
Timer zählt!

Danke!

von Ma B. (drumstick)


Lesenswert?

Hatte den Enable für den Timer Clock vergessen zu posten.

von Ma B. (drumstick)


Lesenswert?

Ich muss präzisieren. Ich lasse den Code auf dem MCBSTM32F400 laufen und 
versuchte zuerst mit den Software Packs ans Ziel zu kommen. Doch die 
Timer sind da noch nicht vorhanden. Bin dann wieder auf die StdLib 
u,gestiegen. Bis auf das RTOS, dies läuft weiterhin über das Pack.

von Ma B. (drumstick)


Lesenswert?

Habe auch einen Thread aufgesetzt, der im Sekundentakt LED an PH3 
alterniert. Dies funktioniert.

von Jürgen H. (nobody)


Lesenswert?

Ich habe dir mal meine PWM Klasse angehängt.
Diese funktionert mit dem STM32100 ohne Probleme.

Vielleicht hilft es dir ja weiter.

1
void CPwm::Init( UINT uiHerz)
2
{
3
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
4
5
   // Enable the TIM3 gloabal Interrupt 
6
   NVIC_InitTypeDef NVIC_InitStructure;
7
   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
8
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
9
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
10
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
11
   NVIC_Init(&NVIC_InitStructure);
12
13
   m_uiTimerPeriod = (SystemCoreClock / uiHerz ) - 1;
14
   // Compute CCR1 value to generate a duty cycle at 99% for channel 1 and 1N 
15
   USHORT usChannelPulse = (USHORT) (((UINT) 99 * (m_uiTimerPeriod - 1)) / 100);
16
   
17
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
18
   TIM_TimeBaseStructure.TIM_Prescaler = 0;
19
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
20
   TIM_TimeBaseStructure.TIM_Period = m_uiTimerPeriod;
21
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
22
   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
23
24
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
25
26
   /* Channel 1, 2,3 and 4 Configuration in PWM mode */
27
   TIM_OCInitTypeDef  TIM_OCInitStructure;
28
   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
29
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
30
   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
31
   TIM_OCInitStructure.TIM_Pulse = usChannelPulse;
32
   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
33
   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
34
   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
35
   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
36
   TIM_OC3Init(TIM2, &TIM_OCInitStructure);
37
38
   // TIM Interrupts enable 
39
   TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
40
   TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);
41
42
   // TIM1 Main Output Enable 
43
   TIM_CtrlPWMOutputs(TIM2, DISABLE);
44
45
   // TIM1 enable counter 
46
   TIM_Cmd(TIM2, ENABLE);
47
}

von Jürgen H. (nobody)


Lesenswert?

Ach ja noch was.

Die Interrupts benötigst du nicht, diese sind noch von früher drinnen.

Und mit dieser Funktion kannst du das dann starten.
1
void CPwm::Start( UCHAR ucPercent )
2
{
3
   SetPercent(ucPercent);
4
5
   GPIO_InitTypeDef  GPIO_InitStructure;
6
7
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
8
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
9
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
10
   ptrcHardware->PinRelay.Init(GPIOA, &GPIO_InitStructure, false);
11
12
   // TIM1 disable counter 
13
   TIM_Cmd(TIM2, ENABLE);
14
   TIM_CtrlPWMOutputs(TIM2, ENABLE);
15
}

von Ma B. (drumstick)


Lesenswert?

Jürgen H. schrieb
> TIM_CtrlPWMOutputs(TIM2, ENABLE);

Diese sind doch nur für Timer 1 und 8?

Vielen Dank!

von Jürgen H. (nobody)


Lesenswert?

Ich kann dir nicht sagen wie es auf deinem Kontroller ist.
Aber bei meinem STM32F100 funktioniert es.

Du setzt ja den F4 ein, denke da wird es schon anders sein.

von Ma B. (drumstick)


Lesenswert?

Ach ja, stimmt! Danke! Langsam gehen mir die Ideen aus....

von Jürgen H. (nobody)


Lesenswert?

Aber du scheinst recht zu haben.

Denke für den Timer 2 ist die Funktion die richtige
1
void TIM_CCxCmd(TIM2, TIM_Channel_3, TIM_CCx_Enable );

Also für meinen Fall.

Die scheint das falsche Register zu beinflussen.

von Ma B. (drumstick)


Lesenswert?

Tatsächlich!! Jetzt funktionierts!!

Habs in den Beispielen nicht gefunden, schon wieder was gelernt!

Vielen Dank für die Hilfe!!

Grüsse

MC

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.