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.
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!
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.
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.
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.
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.
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.
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
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.
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():
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.
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
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.
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:
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.