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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.