Forum: Mikrocontroller und Digitale Elektronik STM32 PWM-Signal


von Robin (Gast)


Lesenswert?

Hallo Ihr,
ich beschäftige ich zum ersten Mal mit einem STM32F100FB 
(STM32VL-Discovery Board), und komme einfach nicht weiter. Habe dieses 
Tutorial und einige Posts in diesem Forum und anderen gelesen, bin 
jedoch nicht weitergekommen 
(http://diller-technologies.de/stm32.html#timer_pwm).

Ich möchte ein PWM-Signal für einen Modelbau-Servo programmieren.
Ich weiss, dass eine Periode 20ms (50Hz) lang sein muss.

Aber da hörts dann auf, das mit den Precalern und Co kappier ich auch 
nicht so wirklich...wäre cool wenn mir jemand das erklären könnte, in 
einer einfachen Darstellung für Micoprozessor neulinge ;-)
Zudem kappiere ich nicht wo ich jetzt genau den DutyCycle verändere, 
auch während der Timer2 an ist.

Vielen Dank schon Mal für eure Tipps :-D

Hier mal mein Code:
1
 
2
3
//// includes------------------------------------------------------------
4
#include <stm32f10x.h>
5
#include <stm32f10x_gpio.h>
6
#include <stm32f10x_rcc.h>
7
#include <stm32f10x_tim.h>
8
#include <stm32f10x_conf.h>
9
10
11
int main(void)
12
{
13
  GPIO_InitTypeDef GPIO_InitStructure;
14
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
15
  TIM_OCInitTypeDef TIM_OC_InitStructure;
16
  
17
  SystemInit();
18
 
19
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB1Periph_TIM2, ENABLE);
20
21
  //Definiert GPIOA mit Pin 1 als Ausgang Alternativ Push-Pull
22
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
23
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
24
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
25
  GPIO_Init(GPIOA, &GPIO_InitStructure);
26
  
27
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
28
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
29
  //Prescaler: Frequenz * PWM Steps= 50 * 1000 = 50kHz
30
  // (72MHz / 50kHz) -1 = 1439
31
  //Period: PWM Steps -1 = 1000-1=999
32
  TIM_TimeBase_InitStructure.TIM_Period = 999;
33
  TIM_TimeBase_InitStructure.TIM_Prescaler = 1439;
34
  TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure); 
35
  
36
  TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
37
  TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
38
  TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
39
  TIM_OC_InitStructure.TIM_Pulse = 100;
40
  
41
  //Channel 2 of Timer2 for PA1
42
  TIM_OC2Init(TIM2, &TIM_OC_InitStructure);
43
  TIM_Cmd(TIM2, ENABLE);
44
45
  
46
while(1){
47
}
48
49
}

von SST (Gast)


Lesenswert?

#define PWM_FREQUENZ              50   // 50 Hz
#define PWM_PRESCALER            100   // div 0
#define PWM_DUTY_SET             100   // 100 %


#define MCK   72000000           //- 72 MHz

#define      PWM_PERIOD    MCK  PWM_PRESCALER  PWM_FREQUENZ //- TIM2
#define      PWM_DUTY_MAX  (PWM_PERIOD-1)

#define      PWM_TIM2(duty)      (u16) (duty * (PWM_PERIOD-1) / 100);

...
  TIM_TimeBase_InitStructure.TIM_Period = PWM_PERIOD -1;
  TIM_TimeBase_InitStructure.TIM_Prescaler = PWM_PRESCALER -1;

  TIM_OC_InitStructure.TIM_Pulse = PWM_TIM2(50);  //- 50%
...


  //- PWM ändern ( OC2 )

  TIM2->CCR2 = PWM_TIM2(50);  //- 1 .. 100 %

von Robin (Gast)


Lesenswert?

Hallo!

Vielen Dank!...leider konnte ich deinen Code nicht kompalieren...
Jedoch habe ich meinen Fehler gefunden
1
 
2
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
3
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

Jedoch würde ich nun gerne wissen wie sich der Prescaler genau berechnet 
wenn ich wie in meinem Falle nun 50 Hz mit einer Unterteilung von 1000 
(Periode).

Vielen dank!

Viele Grüße,

Robin

von Jan H. (jan_h565)


Lesenswert?

Einen F100RB lauft normalerweise mit 24 MHz. Clockinput von TIM1 ist 
damit 24 MHz. TIM1 clock / GPIOclock  auch noch einschalten. Hier meinen 
code :
1
  /* -----------------------------------------------------------------------
2
    TIM1 Configuration: generate 2 PWM signals with 2 different duty cycles:
3
    TIM1CLK = 24 MHz, Prescaler = 23, TIM1 counter clock = 1 MHz
4
    TIM1 ARR Register = 19999=> TIM1 Frequency = TIM1 counter clock/(ARR + 1)
5
    TIM1 Frequency = 50 Hz.
6
    TIM1 Channel1 pulse lenght = TIM1->CCR1 value gives servo between 1000 and 2000 µs
7
    TIM1 Channel4 pulse lenght = TIM1->CCR4 value gives servo between 1000 and 2000 µs
8
    TIM1 update interrupt is enabled, for slow update servoposition !!
9
    Important : N_output TIM1 is on the same pin as remap TIM15, has to be disabled !!
10
  ----------------------------------------------------------------------- */
11
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
12
  TIM_OCInitTypeDef  TIM_OCInitStructure;
13
  /* Time base configuration TIM1*/
14
  TIM_TimeBaseStructure.TIM_Period = 19999;//PWM freq. = 1MHz/20000 = 50Hz , nu 100 Hz,periode=10 ms
15
  TIM_TimeBaseStructure.TIM_Prescaler = 23;// Timer loopt aan 24 MHz/24 = 1MHz
16
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
17
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
18
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //opgelet, interfereert met TIM15
19
  /* PWM1 Mode configuration: TIM 1, Channel1 */
20
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
21
  TIM_OCInitStructure.TIM_Pulse = 1000;//init value van servo 1, zie ook servo functie
22
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
23
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
24
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//nodig voor TIM15 remap !!
25
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
26
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);//geen preload, dus direct in update in register !!!
27
  /* PWM1 Mode configuration: TIM 1, Channel4 */
28
  TIM_OCInitStructure.TIM_Pulse = 2000;//init value van servo 2, zie ook servo functie
29
  TIM_OC4Init(TIM1, &TIM_OCInitStructure);
30
  TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable);

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.