Forum: Mikrocontroller und Digitale Elektronik Timer Interrupt auslösen - STM32F103 (HAL, STM32CubeIDE)


von Christoph K. (chriskuku)


Angehängte Dateien:

Lesenswert?

Ich möchte softwaregetriggert einen Timer (TIM4) im STM32F103 (blue 
pill) starten. Es soll ein 500ms langer Puls (0V) generiert werden. Nach 
den 500ms soll ein Interrupt generiert werden, in dem ich dann (z.B. als 
sichtbare Reaktion) die eingebaute grüne LED (PC13) ausmache.
Es gelingt mir im Moment nicht. Vielleicht kann jemand helfen.
Es soll ja verschiedene Methoden geben, z.B. auch eine PWM 
programmieren.
Oder den Zähler hochzählen lassen. Oder runter auf 0?

Wie starte ich den Timer?

Was muß ich als ISR implementieren (Callback)?

Danke.

: Bearbeitet durch User
von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

Kann das gerade nicht testen, da ich keinen F103 griffbereit habe, und 
ob du das Timing richtig berechnet hast, habe ich nicht nachgerechnet.

Die gröbsten Böcke hab ich mal korrigiert.

Wenn das läuft, sollte die LED im 2s-Takt für 500ms blinken.

Du musst vorher im CubeMX den Code mit der angehängten ioc-Datei 
einmal neu generieren!

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Harry L. schrieb:
> Kann das gerade nicht testen, da ich keinen F103 griffbereit habe, und
> ob du das Timing richtig berechnet hast, habe ich nicht nachgerechnet.
>
> Die gröbsten Böcke hab ich mal korrigiert.
>
> Wenn das läuft, sollte die LED im 2s-Takt für 500ms blinken.
>
> Du musst vorher im CubeMX den Code mit der angehängten ioc-Datei
> einmal neu generieren!

Danke. Was waren die „dicksten Böcke“?
Mußte erst mal einen CubeMX Update fahren. Dann Dateien nach 
STM33CubeIDE/workspace kopiert. Erster Versuch: kein Blinken. Dann kam 
eine Unterbrechung durch ein Sportereignis. Montag auf Achse. Dienstag 
komme ich zum Ausprobieren. melde mich dann wieder.

: Bearbeitet durch User
von Harry L. (mysth)


Lesenswert?

Christoph K. schrieb:
> Danke. Was waren die „dicksten Böcke“?

Der wichtigste Punkt:
Du hast den Timer 2 mal unmittelbar hintereinander gestartet.
Zuerst ohne- und danach nochmal mit Interrupt.
1
  /* USER CODE BEGIN 2 */
2
  HAL_TIM_Base_Start(&htim4);
3
  HAL_TIM_Base_Start_IT(&htim4);
4
  /* USER CODE END 2 */

Der 2. Punkt:
Bei den klassischen Callback-Funktionen sollte man immer prüfen, ob der 
Callback auch zu der verwendeten Peripherie gehört.
1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
2
  if (htim == &htim4)
3
  {
4
    pc13_off();
5
  }
6
}
Das ist in deinem konkreten Fall nicht schlimm, da du nur 1 Timer 
benutzt, aber diese Prüfung sollte man generell machen.
Noch besser ist es, die entsprechende RegisterCallback-Funktion zu 
nutzen, und einen individuellen Callback für die verwendete Peripherie 
zu erstellen.

Zu Letzt noch das Ansprechen der GPIO-Pins.
Das hab ich auf die "HAL-Methode" umgestellt.
Das hat den entscheidenden Vorteil, daß du im CubeMX ein Signal ganz 
einfach auf einen anderen Pin ändern kannst, ohne eine einzige Zeile 
Code zu ändern.
Das vergebene Pin-Label resultiert dann in autom. generierten Makros.

Wenn das jetzt noch nicht läuft, stimmt irgend etwas mit der 
Timer-Konfiguration noch nicht.
Das sollte sich aber leicht im CubeMX anpassen lassen.

Noch ein Tip zum Schluss:
Nutz die CubeIDE!
CubeMX ist darin vollständig integriert.

von Christoph K. (chriskuku)


Lesenswert?

STM32CubeIDE nutze ich ja. Eigentlich will ich von HAL weg. Insofern 
würde michinteressieren, wie die direkte Lösung aussieht.

von Harry L. (mysth)


Lesenswert?

Christoph K. schrieb:
> Eigentlich will ich von HAL weg.

Warum?

Weil hier einige Leute, die das nicht kapiert haben,das verteufeln?

HAL ist schon ziemlich genial, wenn man damit umgehen kann, und kostet 
-ganz im Gegensatz zu dem, was hier einige nix-Checker behaupten, 
praktisch keine Rechenleistung.

von Johnny B. (johnnyb)


Lesenswert?

Harry L. schrieb:
> HAL ist schon ziemlich genial, wenn man damit umgehen kann, und kostet
> -ganz im Gegensatz zu dem, was hier einige nix-Checker behaupten,
> praktisch keine Rechenleistung.

Dem kann ich nur beipflichten. Gerade bei komplexerer Peripherie wie USB 
oder einem ADC kommt man mit CubeMX / HAL sehr schnell zu einem 
funktionierenden Grundkonstrukt.

von Christoph K. (chriskuku)


Lesenswert?

Abgesehen von der - sicher interessanten - HA Debatte zurück zum 
eigentlichen Programm.

Ich habe es geladen in STM32CubeIDE mit GDB Hardware debugger (BMP 
Dongle).

Break vor  HAL_TIM_Base_Start_IT(&htim4);
1
while (1)
2
  {
3
    void pc13_on();
4
>>    HAL_TIM_Base_Start_IT(&htim4);
5
    HAL_Delay(2000);
6
    /* USER CODE END WHILE */
7
8
    /* USER CODE BEGIN 3 */
9
  }

läßt die PC13 LED angehen. Continue läßt sie dann nie mehr angehen in 
der Loop. Ich hatte die Zeitdauer so berechnet: 72MHz /7200 -> 0,1 ms,
von 15535 nach 65535 hochzählen sind 50000 -> 0.5s

von Harry L. (mysth)


Lesenswert?

Setz doch mal einen Breakpoint an den Anfang der Callback-Funktion!

Wird die angesprungen?

Falls du das noch nicht kennst - das ist in dem Zusammenhang sehr 
lesenswert!
https://www.st.com/resource/en/application_note/an4776-generalpurpose-timer-cookbook-for-stm32-microcontrollers-stmicroelectronics.pdf

Ach ja; noch eins:
Über htim4->Instance kannst du direkt auf die Timer-Register zugreifen.
Es könnte Hilfreich sein, die Struktur in einer Live-Expression zu 
beobachten.

: Bearbeitet durch User
von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

So, ich hab das mal auf einem F7-Board nachgebaut.
Den Takt hab ich -wie bei dir- auf 72MHz gestellt, und Caches sind aus.
Mit dieser Konfiguration funktioniert das.

Die Konfiguration solltest du aber praktisch 1:1 übernehmen können.

von Christoph K. (chriskuku)


Lesenswert?

Harry L. schrieb:
> Setz doch mal einen Breakpoint an den Anfang der Callback-Funktion!
>
> Wird die angesprungen?

Ja. Kommt da hinein und schaltet pc13_off():
1
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
2
  if (htim == &htim4)
3
  {
4
>>    pc13_off();
5
  }
6
}

Aber wird nicht wieder eingeschaltet, obwohl es ja in der while loop 
steht.

>
> Falls du das noch nicht kennst - das ist in dem Zusammenhang sehr
> lesenswert!
> 
https://www.st.com/resource/en/application_note/an4776-generalpurpose-timer-cookbook-for-stm32-microcontrollers-stmicroelectronics.pdf

Danke. Sehr guter Hinweis.

>
> Ach ja; noch eins:
> Über htim4->Instance kannst du direkt auf die Timer-Register zugreifen.
> Es könnte Hilfreich sein, die Struktur in einer Live-Expression zu
> beobachten.

von Harry L. (mysth)


Lesenswert?

Christoph K. schrieb:
> Ja. Kommt da hinein und schaltet pc13_off():
> void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
>   if (htim == &htim4)
>   {
>>>    pc13_off();

Sehr gut!
Dann wird der Interrupt ja schon mal ausgelöst.
Dann scheint das ja noch ein Problem mit der Timer-Konfiguration zu 
sein.

von Christoph K. (chriskuku)


Lesenswert?

Beim Einlesen Deines .ioc Files in STM32CubeIDE bekomme ich allerdings 
gesagt, das die Datei von CubeMX 6.7.0 sei, mein Current STM32CubeMX sei 
jedoch 6.6.1. Ich habe STM32CubeMX allerdings vorgestern "geupdated". 
Kann es sein, daß das in CubeIDE integrierte CubeMX das nicht 
mitbekommen hat?

Hatte auch bisher Deine .ioc extra durch CubeMX gejagt um dann die 
Resultate nach IDE rüberzukopieren. (wobei ich mir da jetzt nicht mehr 
so sicher bin - es gab einen Fehler, daß das .ioc read only sei)

Hatte wohl doch geklappt, aber netterweise überschreibt mir CubeMX das 
Projekt in ~/STM32CubeIDE/workspace_1.4.0/oneshot

: Bearbeitet durch User
von Harry L. (mysth)


Angehängte Dateien:

Lesenswert?

Ich verwende die aktuelle CubeIDE Ver. 1.11.0 (siehe Screenshot)
CubeMX ist vollständig integriert in CubeIDE und daher sollte es dabei 
keinen Versions-Konflikt geben.

btw.: ich hatte dir eine PN geschickt.

: Bearbeitet durch User
von Christoph K. (chriskuku)


Lesenswert?

Komisch, daß STM32CubeIDE nicht merkt, daß es veraltet ist (macOS bei 
mir).
Während ich dem Problem jetzt nachjage, kurzer Zwischenbericht, Deine 
letzte Version jetzt zu bauen:
1
arm-none-eabi-gcc "../Core/Src/stm32f1xx_hal_msp.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/stm32f1xx_hal_msp.d" -MT"Core/Src/stm32f1xx_hal_msp.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/stm32f1xx_hal_msp.o"
2
../Core/Src/main.c:21:10: fatal error: eth.h: No such file or directory
3
   21 | #include "eth.h"
4
      |          ^~~~~~~

von Harry L. (mysth)


Lesenswert?

Ja, das war erwartbar, wenn du den Code 1:1 für den F103 übernimmst.
Das war eher zur Anschauung der Einstellungen im CubeMX.

von Christoph K. (chriskuku)


Lesenswert?

Harry L. schrieb:
> Ja, das war erwartbar, wenn du den Code 1:1 für den F103 übernimmst.
> Das war eher zur Anschauung der Einstellungen im CubeMX.

OK, das war jetzt ein Mißverständnis. Dann werde ich das jetzt mal 
übertragen auf F103.

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.