Mikrocontroller und Digitale Elektronik
›
Thread
stm32f4 PWM mit timer 2 Chanel 4 an PB11
MB
Ma B.
(drumstick)
OP
27.03.2014 13:47
#3592723
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
Clock für den Timer ist an?
Wenn mich nicht alles täuscht, hast du für den Timer die Clock
(RCC_AHB1PeriphClockCmd) noch nicht eingeschalten.
MB
Ma B.
(drumstick)
OP
27.03.2014 13:58
#3592746
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!
MB
Ma B.
(drumstick)
OP
27.03.2014 13:59
#3592748
Hatte den Enable für den Timer Clock vergessen zu posten.
MB
Ma B.
(drumstick)
OP
27.03.2014 14:03
#3592755
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.
MB
Ma B.
(drumstick)
OP
27.03.2014 14:06
#3592757
Habe auch einen Thread aufgesetzt, der im Sekundentakt LED an PH3
alterniert. Dies funktioniert.
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 }
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 }
MB
Ma B.
(drumstick)
OP
27.03.2014 14:19
#3592775
Jürgen H. schrieb
> TIM_CtrlPWMOutputs(TIM2, ENABLE);
Diese sind doch nur für Timer 1 und 8?
Vielen Dank!
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.
MB
Ma B.
(drumstick)
OP
27.03.2014 14:24
#3592783
Ach ja, stimmt! Danke! Langsam gehen mir die Ideen aus....
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.
MB
Ma B.
(drumstick)
OP
27.03.2014 14:59
#3592857
Tatsächlich!! Jetzt funktionierts!!
Habs in den Beispielen nicht gefunden, schon wieder was gelernt!
Vielen Dank für die Hilfe!!
Grüsse
MC
↑ Nach oben
← Zurück zu Mikrocontroller und Digitale Elektronik
Antwort schreiben