Forum: Mikrocontroller und Digitale Elektronik STM32F4 mit C (HAL): Timer-PWM, Interrupt, UART


von Nik J. (nikita_j)


Lesenswert?

Hallo liebe Forum User,

im Rahmen eines Projektes habe ich vor eine Servo (Quadcopter-Treiber) 
Ansteuerung mit Discovery-Board (STM32F4-Discovery) zu realisieren. 
Arbeite mit Atolic Truestudio IDE. Zuerst habe ich mit einer 
"stm32f4_discovery.h" LIB in C++ folgende Funktionen realisiert:
- Blink-LED
- PWM-Signal (Timer) (2/20ms+1/20ms Initialisierung + variable Werte von 
1/20ms bis 2/20ms)
- PIN-Interrupt durch ein externen Taster.

Neue Aufgaben führte mich zu Benutzung von CubeMX und damit 
eingebundenen HAL-Library und C.

Folgende Aufgaben müssen realisiert werden:
1. Blink-LED (Erledigt)
2. PWM-Signal (Timer) (2 zu 18ms+ 1 zu 19ms Initialisierung + variable 
Werte von 1 zu 19ms bis 2 zu 18ms Drehzahl) - bin gerade dabei.
3. Interrupt Zähler mit einer Lichtschranke - steht noch vor.
4. Übergabe von PWM Werten über UART-Schnittstelle via Terminal (PUTTY) 
mit Interrupt (Umdrehungszahl des Motors)

Momentan stecke ich bei Aufgabe 2, der Oszilloskop misst kein 
PWM-Signal. Fragen:
-Was könnte im Code Falsch sein?
-Lohnt sich in Berücksichtigung auf 4-8 Motoren in der Zukunft auf C++ 
umzusteigen (Klassen)?
-Lohnt sich HAL-Library zu verwenden? (habe bereits im Forum Gelesen das 
die HAL viele Fehler mitgeschleppt)


Bin für sämtliche Vorschläge Dankbar!
Viele Dank im Voraus! Grüß, NJ

main-Funktion:
1
int main(void)
2
{
3
4
  HAL_Init();
5
6
  SystemClock_Config();
7
8
  MX_GPIO_Init();
9
10
  MX_USART2_UART_Init();
11
12
  MX_TIM4_Init();
13
14
15
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);      //Timer4/CH1 Starten
16
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);      //Timer4/CH2 Starten
17
18
  TIM4->CCR1 =          2000;                    // 2000 == 2 ms
19
  TIM4->CCR2 =          2000;                    // 2000 == 2 ms
20
  HAL_Delay(5000);                               //Verzögerung 5s
21
  TIM4->CCR1 =          1000;                    // 1000 == 1 ms
22
  TIM4->CCR2 =          1000;                    // 1000 == 1 ms
23
  HAL_Delay(5000);                               //Verzögerung 5s
24
25
  while (1)
26
  {
27
   
28
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
29
    HAL_Delay(2000);
30
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
31
    HAL_Delay(2000);
32
    /*Blink-Blink*/
33
34
  }
35
}

Timer-Init:
1
static void MX_TIM4_Init(void)
2
{
3
  TIM_MasterConfigTypeDef             sMasterConfig;
4
  TIM_OC_InitTypeDef                  sConfigOC;
5
6
  PrescalarValue =                    84;
7
8
  htim4.Instance =                    TIM4;
9
  htim4.Init.Prescaler =              PrescalarValue;
10
  htim4.Init.CounterMode =            TIM_COUNTERMODE_UP;
11
  htim4.Init.Period =                 19999;
12
  htim4.Init.ClockDivision =          TIM_CLOCKDIVISION_DIV1;
13
14
  sClockSourceConfig.ClockSource =    TIM_CLOCKSOURCE_ETRMODE2;
15
  sClockSourceConfig.ClockPolarity =  TIM_CLOCKPOLARITY_NONINVERTED;
16
  sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
17
  sClockSourceConfig.ClockFilter =    0;
18
 
19
  HAL_TIM_PWM_Init(&htim4);
20
21
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
22
  sMasterConfig.MasterSlaveMode =     TIM_MASTERSLAVEMODE_DISABLE;
23
  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
24
 
25
  sConfigOC.OCMode =                  TIM_OCMODE_PWM1;
26
  sConfigOC.Pulse = 0;
27
  sConfigOC.OCPolarity =              TIM_OCPOLARITY_HIGH;
28
  sConfigOC.OCFastMode =              TIM_OCFAST_DISABLE;
29
30
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
31
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2);
32
33
  HAL_TIM_MspPostInit(&htim4);
34
}

GPIO-Timer-Init:
1
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
2
{
3
  GPIO_InitTypeDef GPIO_InitStruct;
4
  if(htim->Instance==TIM4)
5
  {
6
    /**TIM4 GPIO Configuration    
7
    PB6     ------> TIM4_CH1
8
    PB7     ------> TIM4_CH2
9
    PB8     ------> TIM4_CH3
10
    PB9     ------> TIM4_CH4 
11
    Hier könnte Ihre Werbung sein!
12
    */
13
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
14
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
15
    GPIO_InitStruct.Pull = GPIO_NOPULL;
16
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
17
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
18
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
19
    }
20
21
}

: Bearbeitet durch User
von stromverdichter (Gast)


Lesenswert?

du hast doch einen eingebauten Debugger an einem Board. Schau doch 
einfach in den Registern nach, wo es klemmt.

von Johnny B. (johnnyb)


Lesenswert?

Nikita J. schrieb:
> Neue Aufgaben führte mich zu Benutzung von CubeMX und damit
> eingebundenen HAL-Library und C.
>
> Folgende Aufgaben müssen realisiert werden:
> 1. Blink-LED (Erledigt)
> 2. PWM-Signal (Timer) (2 zu 18ms+ 1 zu 19ms Initialisierung + variable
> Werte von 1 zu 19ms bis 2 zu 18ms Drehzahl) - bin gerade dabei.
> 3. Interrupt Zähler mit einer Lichtschranke - steht noch vor.
> 4. Übergabe von PWM Werten über UART-Schnittstelle via Terminal (PUTTY)
> mit Interrupt (Umdrehungszahl des Motors)

Ich würde auch gleich noch mittels CubeMX das FreeRTOS einbinden lassen 
und dann alles dort drin implementieren.
Wenn Du mit CubeMX den Code für PWM-Ausgabe erzeugen lässt, musst Du 
noch zusätzlich den Timer sowie die PWM-Einheit (CCR) mittels passenden 
HAL-Funktionen starten.

von Curby23523 N. (Gast)


Lesenswert?

stromverdichter schrieb:
> du hast doch einen eingebauten Debugger an einem Board. Schau doch
> einfach in den Registern nach, wo es klemmt.

Dazu muss man diese aber erstmal verstehen. Und wer nur HAL macht, wird 
das wohl nicht tun.

von Christopher J. (christopher_j23)


Lesenswert?

Nikita J. schrieb:
> -Lohnt sich HAL-Library zu verwenden? (habe bereits im Forum Gelesen das
> die HAL viele Fehler mitgeschleppt)

Ein Fehler ist ganz sicher, dass Leuten wie dir der Eindruck vermittelt 
wird, man bräuchte das Reference-Manual nicht zu lesen, weil CubeMX/HAL 
alles vollautomagisch macht.


Nikita J. schrieb:
> sClockSourceConfig.ClockSource =    TIM_CLOCKSOURCE_ETRMODE2;

Dein Code ist unvollständig. Die Deklaration von sClockSourceConfig 
fehlt aber weißt du denn überhaupt wofür das gut ist? Ich fürchte nicht, 
weil man es für das was du machen willst erstmal gar nicht benötigt.


Nikita J. schrieb:
> /**TIM4 GPIO Configuration
>     PB6     ------> TIM4_CH1
>     [...]
>     Hier könnte Ihre Werbung sein!

Ja ne, is klar.

von PSiem (Gast)


Lesenswert?

Hi,

ob sich die HAL lohnt oder nicht ist wohl eine Glaubensfrage.
Ich programmiere viel damit, im Regelfall funktioniert das auch, 
mindestens genauso viel mache ich aber auch direkt mit den Registern.
Um einen Blick in das Reference Manual kommst du aber so oder so nicht 
drum herum.

Der Init-Code ist aber so nicht von CubeMx erzeugt oder?

Gruß

von Nik J. (nikita_j)


Lesenswert?

Erstmals vielen Dank für ihre zahlreiche Antworten!

stromverdichter schrieb:
> du hast doch einen eingebauten Debugger an einem Board. Schau doch
> einfach in den Registern nach, wo es klemmt.

Hmm, ich befürchte das ich etwas bei Initialisierung falsch gemacht 
habe. Da werde ich aber kaum was verstehen =( Bin in Mikrocontroller 
Bereich ziemlich frisch.

Johnny B. schrieb:
> Nikita J. schrieb:
>> Neue Aufgaben führte mich zu Benutzung von CubeMX und damit
>> eingebundenen HAL-Library und C.
>>
>> Folgende Aufgaben müssen realisiert werden:
>> 1. Blink-LED (Erledigt)
>> 2. PWM-Signal (Timer) (2 zu 18ms+ 1 zu 19ms Initialisierung + variable
>> Werte von 1 zu 19ms bis 2 zu 18ms Drehzahl) - bin gerade dabei.
>> 3. Interrupt Zähler mit einer Lichtschranke - steht noch vor.
>> 4. Übergabe von PWM Werten über UART-Schnittstelle via Terminal (PUTTY)
>> mit Interrupt (Umdrehungszahl des Motors)
>
> Ich würde auch gleich noch mittels CubeMX das FreeRTOS einbinden lassen
> und dann alles dort drin implementieren.
> Wenn Du mit CubeMX den Code für PWM-Ausgabe erzeugen lässt, musst Du
> noch zusätzlich den Timer sowie die PWM-Einheit (CCR) mittels passenden
> HAL-Funktionen starten.

FreeRTOS -> das ist doch eigenes kleines Betriebssystem, richtig? Bittet 
dies größere Vorteile? Ich dachte das die Aufgaben relativ leicht mit 
normalem C-Programm realisierbar sind!?
Timer habe ich doch mit dem Befehl
1
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
 gestartet!?

Curby23523 N. schrieb:
> stromverdichter schrieb:
>> du hast doch einen eingebauten Debugger an einem Board. Schau doch
>> einfach in den Registern nach, wo es klemmt.
>
> Dazu muss man diese aber erstmal verstehen. Und wer nur HAL macht, wird
> das wohl nicht tun.

Christopher J. schrieb:
> Nikita J. schrieb:
>> -Lohnt sich HAL-Library zu verwenden? (habe bereits im Forum Gelesen das
>> die HAL viele Fehler mitgeschleppt)
>
> Ein Fehler ist ganz sicher, dass Leuten wie dir der Eindruck vermittelt
> wird, man bräuchte das Reference-Manual nicht zu lesen, weil CubeMX/HAL
> alles vollautomagisch macht.
>
>
> Nikita J. schrieb:
>> sClockSourceConfig.ClockSource =    TIM_CLOCKSOURCE_ETRMODE2;
>
> Dein Code ist unvollständig. Die Deklaration von sClockSourceConfig
> fehlt aber weißt du denn überhaupt wofür das gut ist? Ich fürchte nicht,
> weil man es für das was du machen willst erstmal gar nicht benötigt.
>
>
> Nikita J. schrieb:
>> /**TIM4 GPIO Configuration
>>     PB6     ------> TIM4_CH1
>>     [...]
>>     Hier könnte Ihre Werbung sein!
>
> Ja ne, is klar.

Reference Manual habe ich. Vollständig durchgelesen - nicht.
1
sClockSourceConfig.ClockSource =    TIM_CLOCKSOURCE_ETRMODE2;
 - wähle ich nicht damit die Clock-Quelle was mein Timer verwendet?
Warum brauche ich das für meine Realisierung nicht?

PSiem schrieb:
> Hi,
>
> ob sich die HAL lohnt oder nicht ist wohl eine Glaubensfrage.
> Ich programmiere viel damit, im Regelfall funktioniert das auch,
> mindestens genauso viel mache ich aber auch direkt mit den Registern.
> Um einen Blick in das Reference Manual kommst du aber so oder so nicht
> drum herum.
>
> Der Init-Code ist aber so nicht von CubeMx erzeugt oder?
>
> Gruß

OK, ohne Reference Manual komme ich anscheinend nicht weiter...
Also, ich habe zwar GPIOs, UARTs, EXTIs und TIMs mit CubeMX erzeugt aber 
dabei etwas rumgebastelt, den es nicht so funktioniert hat wie ich mir 
vorstellte.

von Walt N. (belayason)


Lesenswert?

Wenn wir gerade beim Thema sind. Ich bin auch neu in der HAL Umgebung. 
Habe einen fertigen code der mir Sensordaten ausließt den ich auf mein 
NUCLEO-F411RE drauf gesteckt habe. Wie gehe ich da am besten ran? Ich 
kenne mich ja schon nicht mit der HAL library aus, deswegen tu ich mir 
gerade sehr schwer. Soll ich den Sensor erstmal weglassen und mich mit 
meinem Board auseinandersetzen?

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.