Forum: Mikrocontroller und Digitale Elektronik STM32F4 PWM Problem


von Kristoffer Ullsten (Gast)


Lesenswert?

Hallo,

auf dem STM32F4 Discovery Board versuche ich die 3 Phasen PWMs mit den 
komplementären Ausgängen zu generieren. Seltsamerweise funktioniert es 
**nur** bei PA9 nicht. Weiss jemand woran es liegt. Ich habe die GPIO 
Timer sehr gründlich initialisiert.
1
    /* GPIOA GPIOB and GPIOC clock enable */
2
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
3
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
4
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
5
6
    /* TIM1 clock enable APB2 = 84MHz */
7
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
8
9
    GPIO_InitTypeDef GPIO_InitStructure;
10
11
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
12
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
13
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
14
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
15
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
16
    GPIO_Init(GPIOA, &GPIO_InitStructure);
17
18
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
19
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1);
20
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);
21
22
23
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
24
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
25
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
26
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
27
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
28
    GPIO_Init(GPIOB, &GPIO_InitStructure);
29
    
30
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_TIM1);
31
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_TIM1);
32
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);
33
34
    uint16_t TimerPeriod = 4200;
35
    uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;
36
    /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
37
    Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
38
39
    /* Compute CCR2 value to generate a duty cycle at 25%  for channel 2 */
40
    Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
41
42
    /* Compute CCR3 value to generate a duty cycle at 12.5%  for channel 3 */
43
    Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000);
44
45
    /* PWM_fr = TIM_CLK_fr / (Prescaler + 1) / (Period + 1)  TIM_CLK_fr = 84MHz */
46
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
47
    TIM_OCInitTypeDef  TIM_OCInitStructure;
48
    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
49
50
    TIM_TimeBaseStructure.TIM_Prescaler = 1;
51
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
52
    TIM_TimeBaseStructure.TIM_Period = 4200 - 1;
53
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
54
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
55
56
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
57
58
    /* Channel 1, 2 and 3 Configuration in PWM mode */
59
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
60
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
61
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
62
    TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;
63
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
64
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
65
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
66
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
67
68
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
69
70
    TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;
71
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
72
    
73
    TIM_OCInitStructure.TIM_Pulse = Channel3Pulse;
74
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
75
76
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
77
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
78
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
79
80
    /* Automatic Output enable, Break, dead time and lock configuration*/
81
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
82
    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
83
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
84
    TIM_BDTRInitStructure.TIM_DeadTime = 11;
85
    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
86
    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
87
    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
88
89
    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
90
    TIM_CCPreloadControl(TIM1, ENABLE);
91
    TIM_ARRPreloadConfig(TIM1, ENABLE);
92
93
    /* TIM1 counter enable */
94
    TIM_Cmd(TIM1, ENABLE);
95
96
    /* Main Output Enable */
97
    TIM_CtrlPWMOutputs(TIM1, ENABLE);

von Kristoffer Ullsten (Gast)


Angehängte Dateien:

Lesenswert?

Die mittlere blau Kurve ist PA9. Ich bin am verzweifeln.
1
/* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
2
Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
3
4
/* Compute CCR2 value to generate a duty cycle at 25%  for channel 2 */
5
Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
6
7
/* Compute CCR3 value to generate a duty cycle at 12.5%  for channel 3 */
8
Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000);
9
10
    while (1)
11
    {
12
13
        STM_EVAL_LEDToggle(LED3);
14
        STM_EVAL_LEDToggle(LED4);
15
        STM_EVAL_LEDToggle(LED5);
16
        STM_EVAL_LEDToggle(LED6);
17
        Delay(1e5);
18
        TIM1->CCR1 = Channel3Pulse;
19
        TIM1->CCR2 = Channel3Pulse;
20
        TIM1->CCR3 = Channel3Pulse;
21
22
23
    }

von Sergey (Gast)


Lesenswert?

Mh.. Auf dem Discovery Board ist PA9 belegt mit LED/VBUS von dem USB. 
Vielleicht macht das ja ärger.

von Kristoffer Ullsten (Gast)


Lesenswert?

Sergey schrieb:
> Mh.. Auf dem Discovery Board ist PA9 belegt mit LED/VBUS von dem
> USB.
> Vielleicht macht das ja ärger.

stimmt. das sehe ich grad. Ich habe PC0 auf HIGH gesetzt. keine 
Verbesserung

von Kristoffer Ullsten (Gast)


Angehängte Dateien:

Lesenswert?

..

von hp-freund (Gast)


Lesenswert?

Moin,
ich habe den Code nur kurz überflogen, aber:

1. steht was von verschiedenen duty cycle, Imulse sind aber gleich lang
2. hängt an PA9 noch ein 4,7µF Kondensator

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Kristoffer Ullsten schrieb:
> ..

Das ist wohl jedem schonmal passiert. :)

Im Handbuch zu den jeweiligen DISCO-Boards gibt es eine Belegungsliste 
für die Ports. Die ist gerne mal übersichtlicher, als Papier-/PDF-Pläne.

Cheerio,
 marcus

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Freund Uwe B. hat die Pinbelegung des STM32F4 Disco sehr schön auf HTML:
http://mikrocontroller.bplaced.net/wordpress/wp-content/uploads/2013/03/Pinbelegung_v101.html
Aber mein Eindruck ist, das der Te auf dem Holzweg ist. Man macht ja 
keine um 120° verschobenen Phasen mit den CC Registern, sondern die 
dienen doch der Bestromung des Motors und damit der Drehzahl Steuerung.
Ausserdem verlegt man die ganzen Outputs des Timer1 am besten auf PE8 - 
PE13, die beim Disco Board frei sind und auch die komplementären Kanäle 
bereitstellen.

: Bearbeitet durch User
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.