Forum: Mikrocontroller und Digitale Elektronik PWM Signal mit HAL STM32


von HAL (Gast)


Lesenswert?

Hallo,

ich möchte mit Hilfe der HAL Bibliothek ein PWM Signal erzeugen.

Meine Schritte bisher sind:

Initialisierungscode von CubeMX.

Aufruf der Funktionen wie folgt:

MX_TIM4_Init();
HAL_TIM_PWM_Init(&htim4);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_ALL);

Fehlt da irgendwie noch etwas?
Leuchten tut keine einzige meiner LEDs...

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


Lesenswert?

Öh, stellst du den irgendwo das Tastverhältnis ein? Davon sehe ich 
nichts, aber vllt. bin ich für HAL zu doof.
Mit SPL muss ich dem Timer und dem jeweiligen CC Register sagen, das ich 
PWM machen möchte und auch noch den PWM Pin auf Ausgang stellen, bzw. 
die Alternate Function aktivieren.

von HAL (Gast)


Lesenswert?

Die Init Funktion sieht wie folgt aus:
Frequenz sind 42MHz.

1
/* TIM4 init function */
2
void MX_TIM4_Init(void)
3
{
4
5
  TIM_ClockConfigTypeDef sClockSourceConfig;
6
  TIM_MasterConfigTypeDef sMasterConfig;
7
  TIM_OC_InitTypeDef sConfigOC;
8
9
  htim4.Instance = TIM4;
10
  htim4.Init.Prescaler = 420;
11
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
12
  htim4.Init.Period = 10000;
13
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
14
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
15
  {
16
    Error_Handler();
17
  }
18
19
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
20
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
21
  {
22
    Error_Handler();
23
  }
24
25
  if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
26
  {
27
    Error_Handler();
28
  }
29
30
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
31
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
32
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
33
  {
34
    Error_Handler();
35
  }
36
37
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
38
  sConfigOC.Pulse = 100;
39
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
40
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
41
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
42
  {
43
    Error_Handler();
44
  }
45
46
  sConfigOC.Pulse = 1000;
47
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
48
  {
49
    Error_Handler();
50
  }
51
52
  sConfigOC.Pulse = 5000;
53
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
54
  {
55
    Error_Handler();
56
  }
57
58
  sConfigOC.Pulse = 15000;
59
  if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
60
  {
61
    Error_Handler();
62
  }
63
64
  HAL_TIM_MspPostInit(&htim4);

von HAL (Gast)


Lesenswert?

Die Funktion HAL
_TIM_MspPostInit(&htim4) sieht so aus:
1
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
2
{
3
4
  GPIO_InitTypeDef GPIO_InitStruct;
5
  if(htim->Instance==TIM4)
6
  {
7
  /* USER CODE BEGIN TIM4_MspPostInit 0 */
8
9
  /* USER CODE END TIM4_MspPostInit 0 */
10
  
11
    /**TIM4 GPIO Configuration    
12
    PD12     ------> TIM4_CH1
13
    PD13     ------> TIM4_CH2
14
    PD14     ------> TIM4_CH3
15
    PD15     ------> TIM4_CH4 
16
    */
17
    GPIO_InitStruct.Pin = LD1|LD2|LD3|LD4;
18
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
19
    GPIO_InitStruct.Pull = GPIO_NOPULL;
20
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
21
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
22
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
23
24
  /* USER CODE BEGIN TIM4_MspPostInit 1 */
25
26
  /* USER CODE END TIM4_MspPostInit 1 */
27
  }
28
29
}

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


Lesenswert?

HAL schrieb:
> Die Funktion HAL
> _TIM_MspPostInit(&htim4) sieht so aus:

Fein. Aber wo rufst du die auf? In deinem ersten Post ist davon nichts 
zu sehen.

HAL schrieb:
> if(htim->Instance==TIM4)

Und warum diese Einschränkung? Ist doch völlig wurscht, denn du 
initialisierst ja nur ein paar Pins.

HAL schrieb:
> sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
>   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
>   if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) !=
> HAL_OK)
>   {
>     Error_Handler();
>   }

Auf dieses Feature solltest du erstmal verzichten, wenns dir auf die PWM 
ankommt. Wenn die läuft, kannst du mit dem Trigger rumspielen. Ist das 
ein Discovery F407 Board?

von HAL (Gast)


Lesenswert?

PostInit wird am Ende von Init aufgerufen.

Habe die geschweifte Klammer vergessen zu kopieren.

von HAL (Gast)


Lesenswert?

Vielleicht sollte man sich nicht so sehr an den einzelnen Funktionen 
aufhängen, die sind mir so von der HAL übergeben worden, bzw. von Cube 
erzeugt. Insofern erwarte ich, dass die irgendwie schon tun was sie tun 
sollen.

Meine Frage ziel also eher darauf, ob ich irgendetwas grundlegendes 
vergessen habe, ob ich noch irgendeine Funktion im Vorwege aufrufen muss 
und dergleichen...

von hp-freund (Gast)


Lesenswert?

Habe jetzt keine Lust alles zu lesen / zu prüfen, aber:

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

mach den mal schnell.

von hp-freund (Gast)


Lesenswert?

Und? Wie sieht es jetzt aus?

von KeilBenutzer (Gast)


Lesenswert?

TIM_CHANNEL_4 wird nicht funktionieren, da:

sConfigOC.Pulse = 15000 > htim4.Init.Period = 10000.

Außerdem wird dein HAL_TIM_PWM_Init(&htim4); schon in der MSP-Init davor 
durchgeführt, hier überschreibst du evtl. dein korrekt initialisierten 
Timer4.

von here (Gast)


Lesenswert?

Funktionieren die LEDs ohne PWM?
Die Taktversorgung von GPIO und Timer sind aktiviert?

von HAL (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hab endlich Zeit an dem Problem weiter zu arbeiten, aber so ganz will es 
noch nicht. IRgendwas mache Ich immer noch falsch.

Der Timer scheint zu laufen, das CNT Register wird hoch gezählt. Die 
LEDs machen leider garnichts.

Das PRogramm ist nun so minimalistisch wie möglich, da kann doch 
eigentlich Nur eine Kleinigkeit fehlen, weiß einfach nicht was es ist...

Im Screenshot sieht man mein Programm und das Timer4Register.



Was fehlt denn noch, damit bei Erreichen der jerweiligen Timer-Werte 
auch die LED mal umgeschaltet wird?


Und eine Sache verstehe ich irgendwie auch noch nicht so ganz:
Man kann die PWM ja "normal" starten und mit dem Zusat "_IT" um einen 
Interrupt  zu aktivieren. Kommt mir irgendwie spanisch vor, weil nutzt 
man nicht gerade die PWM, um nicht dauernd Timer-Interrupts aus zu 
lösen, sondern Portpins eben im Hintergrund ohne Prozessorlast um zu 
schalten?

von hp-freund (Gast)


Lesenswert?

HAL schrieb:
> HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_ALL);

Starte mal einen einzelnen Kanal.

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.