STM32 Servoansteuerung PWM

OP #2511446
Lesenswert?

Hallo,

bin neu hier und möchte eine PWM
mit Hilfe des TIM1 Kanal2 entwickeln.

Ich besitze das IAR STM32-SK Board mit dem J-Link Debugger.
Laut mitgeliefertem Schaltplan sitzt der TIM_CH2 auf Pin A9.
Meine erste Frage. Wie gebe ich den Pin korrekt an?
1
void main(void)
2
{
3
  GPIO_InitTypeDef          GPIO_InitStructure;
4
  TIM_TimeBaseInitTypeDef   TIM1_TimeBaseInitStruct;
5
  TIM_OCInitTypeDef         TIM_OCInitStructure;
6
  
7
  SystemInit();
8

9
  /* Set the Vector Table base location at 0x20000000 */
10
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
11
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
12

13
  // Enable GPIO clock and release reset
14
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
15
                         RCC_APB2Periph_AFIO,
16
                         ENABLE);
17
  
18
  // Timer1 Init
19
  // Enable Timer1 clock and release reset
20
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
21
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_TIM1,DISABLE);
22
  
23
  // Setup 
24
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9;
25
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
26
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
27
  GPIO_Init(GPIOA, &GPIO_InitStructure);

Das war meine Initialisierun der Main Methode.
Danach stelle ich die Timer ein.
Ich möchte damit einen Modellbau Servo ansteuern.
Das heisst: 0.5 bis 2.5ms variable Pulsweite
und eine Periodendauer von 20ms.
1
  // Set timer period 1.5 ms
2
  TIM1_TimeBaseInitStruct.TIM_Prescaler = 720;  // 720 = 10us resolution
3
  TIM1_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
4
  TIM1_TimeBaseInitStruct.TIM_Period = 150;  // 10000 = 100 ms  200 = 2ms  50 = 0.5ms
5
  TIM1_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
6
  TIM1_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
7
  TIM_TimeBaseInit(TIM1,&TIM1_TimeBaseInitStruct);
8
  
9
  //TIM_OCStructInit( &TIM_OCInitStruct );
10
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
11
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
12
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
13
  TIM_OCInitStructure.TIM_Pulse = 500;
14
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
15
 
16
  // TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
17
  TIM_Cmd( TIM1, ENABLE );
18
  
19
  //PWM1 Mode configuration: TIM 1, Channel2
20
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
21
  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
22
  
23
  while(1)
24
  {
25
    
26
  }
27
}

Nun funktioniert aber die PWM aber nicht.
Ich bekomme kein Signal.
Was mache ich falsch.
Wie kann ich während der Laufzeit die Pulsweite ändern?

Wäre echt lieb wenn mir von euch jemand helfen könnte.

lg Kerstin.
Persönliche Seite #2511455
Lesenswert?

Hi, ich habe gerade keine Muße deinen Code zu analysieren, aber ich kann 
dir eben meinen funktionierenden Code hinklatschen zum Selbststudium:
1
// TimeBase
2
TIM_TimeBaseInitTypeDef timBase;
3

4
TIM_TimeBaseStructInit (&timBase);
5
timBase.TIM_Prescaler = ((SystemCoreClock / 2 ) / 1000000)-1;
6
timBase.TIM_ClockDivision = TIM_CKD_DIV1;
7
timBase.TIM_CounterMode = TIM_CounterMode_Up;
8
timBase.TIM_Period = 20000;
9
TIM_TimeBaseInit (TIM4, &timBase);
10
TIM_ARRPreloadConfig (TIM4, ENABLE);
11

12
// Update registers
13
TIM4->EGR |= (1 << TIM_EGR_UG);
14

15
// Output compare match
16
TIM_OCInitTypeDef oc;
17
TIM_OCStructInit (&oc);
18

19
oc.TIM_OCIdleState = TIM_OCIdleState_Reset;
20
oc.TIM_OCNIdleState = TIM_OCNIdleState_Set;
21
oc.TIM_OCMode = TIM_OCMode_PWM1;
22
oc.TIM_OCPolarity = TIM_OCPolarity_High;
23
oc.TIM_OutputState = TIM_OutputState_Enable;
24
oc.TIM_Pulse = 1500; // Initiale Pulsweite in Millisekunden
25

26
TIM_OC1Init (TIM4, &oc);
27
TIM_OC1PreloadConfig (TIM4, TIM_OCPreload_Enable);
28

29
TIM_BDTRInitTypeDef bdtr;
30
TIM_BDTRStructInit (&bdtr);
31
bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
32
TIM_BDTRConfig (TIM4, &bdtr);
33

34
// Start the timer
35
TIM_Cmd (TIM4, ENABLE);
36

37
// Configure GPIO Pin
38
RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIODEN, ENABLE);
39
GPIO_InitTypeDef GPIO_InitStructure;
40
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
41
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
42
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
43
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
44
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
45
GPIO_Init(GPIOD, &GPIO_InitStructure);
46
GPIO_PinAFConfig (GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
47

48
// Ändern der Pulsweite:
49
TIM_SetCompare1 (TIM4, 1500); // Pulsweite in Millisekunden
Bei der GPIO-Konfiguration muss man natürlich den richtigen Pin 
erwischen, bei meinem STM32F4407VG ist das PD12. Herausfinden kann man 
den richtigen Pin aus der "Alternate function mapping" aus dem 
Datenblatt.
Persönliche Seite #2511950
Lesenswert?

Indem du diesen Abschnitt
1
// Output compare match
2
TIM_OCInitTypeDef oc;
3
TIM_OCStructInit (&oc);
4

5
oc.TIM_OCIdleState = TIM_OCIdleState_Reset;
6
oc.TIM_OCNIdleState = TIM_OCNIdleState_Set;
7
oc.TIM_OCMode = TIM_OCMode_PWM1;
8
oc.TIM_OCPolarity = TIM_OCPolarity_High;
9
oc.TIM_OutputState = TIM_OutputState_Enable;
10
oc.TIM_Pulse = 1500; // Initiale Pulsweite in Millisekunden
11

12
TIM_OC1Init (TIM4, &oc);
13
TIM_OC1PreloadConfig (TIM4, TIM_OCPreload_Enable);
Für jeden der gewünschten, max. 4 Channels, 1x ausführst. Du musst dann 
das OC1* durch OC2, etc. ersetzen.
Gleiches gilt für:
1
TIM_SetCompare1 (TIM4, 1500); // Pulsweite in Millisekunden
OP #2512232
Lesenswert?

Kein Problem habs schon kapiert.
Hab nun alles so eingebaut.

Wenn ich das Signal des RC-Empfängers mit angeschlossenem Servo in 
MITTELSTELLUNG messe ist die Periodendauer 22ms lang und hat eine
Pulsweite von 1,48ms

Wenn ich dies mit dem Microcontroller nachahme
habe ich zwar auf dem DSO das gleiche Bild, jedoch fährt der
Servo immer an den Anschlag....

Wieso?
Gast #2512238
Lesenswert?

>Wenn ich dies mit dem Microcontroller nachahme
>habe ich zwar auf dem DSO das gleiche Bild, jedoch fährt der
>Servo immer an den Anschlag....

Vieleicht mag der Servo ja keine 3.3V sondern möchte
5V haben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren