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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Nikita J. (nikita_j)


Bewertung
0 lesenswert
nicht 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:
int main(void)
{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_USART2_UART_Init();

  MX_TIM4_Init();


  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);      //Timer4/CH1 Starten
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);      //Timer4/CH2 Starten

  TIM4->CCR1 =          2000;                    // 2000 == 2 ms
  TIM4->CCR2 =          2000;                    // 2000 == 2 ms
  HAL_Delay(5000);                               //Verzögerung 5s
  TIM4->CCR1 =          1000;                    // 1000 == 1 ms
  TIM4->CCR2 =          1000;                    // 1000 == 1 ms
  HAL_Delay(5000);                               //Verzögerung 5s

  while (1)
  {
   
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_Delay(2000);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(2000);
    /*Blink-Blink*/

  }
}

Timer-Init:
static void MX_TIM4_Init(void)
{
  TIM_MasterConfigTypeDef             sMasterConfig;
  TIM_OC_InitTypeDef                  sConfigOC;

  PrescalarValue =                    84;

  htim4.Instance =                    TIM4;
  htim4.Init.Prescaler =              PrescalarValue;
  htim4.Init.CounterMode =            TIM_COUNTERMODE_UP;
  htim4.Init.Period =                 19999;
  htim4.Init.ClockDivision =          TIM_CLOCKDIVISION_DIV1;

  sClockSourceConfig.ClockSource =    TIM_CLOCKSOURCE_ETRMODE2;
  sClockSourceConfig.ClockPolarity =  TIM_CLOCKPOLARITY_NONINVERTED;
  sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
  sClockSourceConfig.ClockFilter =    0;
 
  HAL_TIM_PWM_Init(&htim4);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode =     TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
 
  sConfigOC.OCMode =                  TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity =              TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode =              TIM_OCFAST_DISABLE;

  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
  HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2);

  HAL_TIM_MspPostInit(&htim4);
}

GPIO-Timer-Init:
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(htim->Instance==TIM4)
  {
    /**TIM4 GPIO Configuration    
    PB6     ------> TIM4_CH1
    PB7     ------> TIM4_CH2
    PB8     ------> TIM4_CH3
    PB9     ------> TIM4_CH4 
    Hier könnte Ihre Werbung sein!
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }

}

: Bearbeitet durch User
von stromverdichter (Gast)


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

von Johnny B. (johnnyb)


Bewertung
0 lesenswert
nicht 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. (nils_h494)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Nikita J. (nikita_j)


Bewertung
0 lesenswert
nicht 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
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.
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)


Bewertung
0 lesenswert
nicht 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?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.