Forum: Mikrocontroller und Digitale Elektronik STM32 - Timer steht still


von Terence S. (takeshi)



Lesenswert?

Hallo zusammen,

ich habe hier ein Platinchen mit einem STM32G071CB, externem Quarz, 
Tastern, LEDs und weiterer Peripherie. Um zu testen, ob der 
Microcontroller überhaupt läuft, habe ich ein kleines Programm 
geschrieben, das einen Taster auswertet und davon abhängig eine LED 
angesteuert - er läuft.

Nun wollte ich eine PWM generieren, habe dafür PA8 auf TIM1_CH1 und PA2 
auf TIM15_CH1 konfiguriert. Bei beiden (und bei TIM16) haben ich die 
Clock Source auf "Internal Clock" gestellt, "Counter Period" auf 10000 
gestellt und "auto-reload preload" auf "Enable". Ich bekomme aber keine 
PWM heraus. Daraufhin bin ich zur Problemanalyse direkt an die Wurzel 
gegangen und mir den Zählerwert der Timer angeschaut. Dazu das Programm 
geschrieben, gestartet, angehalten und im reiter SFRs den Wert vom 
Register CNT angeschaut. Der ist immer 0, egal welcher Timer. Damit ist 
für mich klar, warum da keine PWM herauskommt, aber noch nicht, warum 
der Zähler sich nicht verändert. Um den externen Quarz auszuschließen, 
habe ich wieder auf die interne Taktquelle umgestellt, aber keine 
Änderung. Daher meine Frage, woran könnte das liegen?

Anbei noch die Bilder von der Konfiguration. Wenn noch weitere 
Informationen gebraucht werden, gern erfragen.

von Michael J. (jogibaer)


Lesenswert?

Hallo,

hast Du denn auch einen Wert ins ARR Register geschrieben?
Ist das zugehörige CEN Bit gesetzt?

Jogibär

PS: Code ist mir lieber als diese klikibunti Bilder.

von Christian (christiankpunkt)


Lesenswert?

fehlt das eventuell:
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;

von Wastl (hartundweichware)


Lesenswert?

Terence S. schrieb:
> Wenn noch weitere
> Informationen gebraucht werden, gern erfragen.

Was hindert dich daran, dein *.ioc File zu posten? Ist deine
Kreation so geheim dass man sie nicht nachvollziehen darf?

Ein komplettes Projekt (ohne *.obj und sonstigen Debug-Ballast)
wäre noch hilfreicher ...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Du hast nur im CubeMX konfiguriert aber keinen Code geschrieben? Du 
musst den Timer auch starten. Die Funktion heißt HAL_TIM_Base_Start oder 
so ähnlich... Normalerweise in die main(), vor die Endlosschleife.

: Bearbeitet durch User
von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Terence S. schrieb:
> Daher meine Frage, woran könnte das liegen?

Einerseits hat Dein Timer den Startschuss nicht gehört (Enable), 
andererseits muss man, soweit ich mich erinnern kann, vermutlich auch 
die Ausgänge und Kanäle einschalten (Enable). Du wirst Dich leider mit 
den Registern Deines Timers beschäftigen und dort im Reference Manual 
nachschauen müssen, wo das ist und was das ist. Alternativ kann man das 
bestimmt auch über das Datenblatt mit den HAL- und LL-Funktionen 
herausfinden und entsprechend einschalten.

von Wastl (hartundweichware)


Lesenswert?

Gregor J. schrieb:
> Du wirst Dich leider mit
> den Registern Deines Timers beschäftigen und dort im Reference Manual
> nachschauen müssen

Nein!

Gregor J. schrieb:
> Alternativ kann man das
> bestimmt auch über das Datenblatt mit den HAL- und LL-Funktionen
> herausfinden und entsprechend einschalten

Ja!

Man kann heutztage praktisch alle Register eines Controllers mittels
HAL-Lib- oder LL-Lib-Funktionen und -Makros steuern ohne jemals ein
Controller-Register genannt oder adressiert haben zu müssen. Und das
in den meisten Fällen ohne Zeitverlust im Maschinencode. Ausgenommen
möglicherweise HAL-Aufrufe in denen komplexe Abläufe realisiert
sind.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Wastl schrieb:
> Nein!

Da hat wohl einer eine Registerallergie oder -aversion – keine schöne 
Sache. Wie ich bereits sagte, man sollte sich so früh wie möglich mit 
dem passenden Reference Manual anfreunden und dort stehen nun mal die 
Register, ob es einem passt oder nicht.

___
> Man kann heutztage praktisch alle Register eines Controllers mittels
> HAL-Lib- oder LL-Lib-Funktionen und -Makros steuern ohne jemals ein
> Controller-Register genannt oder adressiert haben zu müssen. Und das
> in den meisten Fällen ohne Zeitverlust im Maschinencode. Ausgenommen
> möglicherweise HAL-Aufrufe in denen komplexe Abläufe realisiert
> sind.

Hört sich nach Arduino-Vorgehensweise an. Die Strategie „Bloß keine 
Register in meinem Leben” wird eines Tages nicht aufgehen und voll in 
die Hose gehen.

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Gregor J. schrieb:
> Hört sich nach Arduino-Vorgehensweise an.

Hört sich nach "keiner Ahnung" an was im HAL- und LL-Gefüge
gemacht wird bzw. was damit zu tun hat.

Bei Arduino instanziert man Klassen und ruft deren Methoden auf.
Das hat mit Programmierung im Sinne von HAL und LL nicht im
Entferntesten etwas zu tun. Also lieber mal still sein wenn
man es nicht besser weiss.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Wastl schrieb:
> Hört sich nach "keiner Ahnung"

Ja, das hört sich tatsächlich auch nach „keine Ahnung” an, wenn man 
Register beim STM32 völlig meiden und verbannen will.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Gregor J. schrieb:
> oweit ich mich erinnern kann, vermutlich auch
> die Ausgänge und Kanäle einschalten (Enable)

Das macht der generierte Code automatisch. Man muss den Timer lediglich 
noch starten.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Niklas G. schrieb:
> Das macht der generierte Code automatisch. Man muss den Timer lediglich
> noch starten.

Das Durchgeklickte und der daraus generierte Code macht eben leider 
nicht alles automatisch – deswegen erwähne ich es auch. Das kann von µC 
zu µC und auch von Timer zu Timer innerhalb eines µControllers variieren 
– und genau deswegen sollte man sich in das passende Reference Manual 
vertiefen, um das herausfinden zu können.

: Bearbeitet durch User
von Wastl (hartundweichware)


Angehängte Dateien:

Lesenswert?

Gregor J. schrieb:
> Das Durchgeklickte und der daraus generierte Code macht eben leider
> nicht alles automatisch

Und das ist auch seitens STM so beabsichtigt. Wer weiss was
der User genau machen will - sicherlich nicht bei einer
Vielzahl von initialisierten Timern einfach mal alles starten
was so da ist und Unheil anrichten könnte.

Dafür gibt es mundgerecht in den HAL- und LL-Libs einfache
Aufrufe - wiederum ohne Register-Adressen oder -Namen sondern
als sinnbringende Makros. Siehe Anhang.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Wastl schrieb:
> Dafür gibt es mundgerecht in den HAL- und LL-Libs einfache
> Aufrufe - wiederum ohne Register-Adressen oder -Namen sondern
> als sinnbringende Makros. Siehe Anhang.

Dafür gibt es vor allem das Reference Manual – wo man zuerst nachschauen 
und nachforschen sollte, auch als Registerallergiker. Danach kann man 
sich dann den passenden Weg für einen aussuchen – es gibt was für 
Registerallergiker und auch etwas für Leute, die weniger oder gar keine 
Registerallergie haben. Wie gewohnt – ohne Fleiß kein Preis.

von Rahul D. (rahul)


Lesenswert?

Wastl schrieb:
> Dafür gibt es mundgerecht in den HAL- und LL-Libs einfache
> Aufrufe - wiederum ohne Register-Adressen oder -Namen sondern
> als sinnbringende Makros. Siehe Anhang.

Die auch wunderbar dokumentiert sind.

Gregor J. schrieb:
> Dafür gibt es vor allem das Reference Manual – wo man zuerst nachschauen
> und nachforschen sollte, auch als Registerallergiker. Danach kann man
> sich dann den passenden Weg für einen aussuchen – es gibt was für
> Registerallergiker und auch etwas für Leute, die weniger oder gar keine
> Registerallergie haben. Wie gewohnt – ohne Fleiß kein Preis.

Und jedesmal das Rad neu erfinden?
Am Besten noch mit den absoluten Speicheradressen arbeiten. Wozu man 
sich wohl sowas wie Makros und Libs ausgedacht hat.
Das Reference Manual hat seine Daseinsberechtigung - HAL- und LL-Libs 
erleichtern das Leben.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Rahul D. schrieb:
> Und jedesmal das Rad neu erfinden?

Selbstverständlich nicht – aber einen auf Deutsch geschriebenen Text 
muss man vorher auch richtig verstehen können, was ich explizit vor so 
einem Reference Manual empfehle, dann erübrigen sich solche und ähnliche 
unsinnigen Unterstellungen.

__
> Am Besten noch mit den absoluten Speicheradressen arbeiten. Wozu man
> sich wohl sowas wie Makros und Libs ausgedacht hat.
> Das Reference Manual hat seine Daseinsberechtigung - HAL- und LL-Libs
> erleichtern das Leben.

Wenn Du meine Aussage verstanden hättest, bräuchtest Du solche absurden 
Sachen nicht zu schreiben.

: Bearbeitet durch User
von Monk (Gast)


Lesenswert?

Die knappe Doku der HAL alleine reicht nicht. Nur zusammen mit dem 
Reference Manual erfährt man, was die einzelnen HW Komponenten können, 
und wie sie zusammen spielen ( bzw. welche Kombinationen nicht gehen ).

Ohne Reference Manual kommt es schnell dazu, dass man Funktionalität 
erwartet, die nicht vorhanden ist. Gleiches Thema wie bei Arduino.

Die HAL vereinheitlicht die Nutzung der STM32, und erleichtert damit die 
Portierung von Code auf andere STM32 Modelle.

von Rahul D. (rahul)


Lesenswert?

Gregor J. schrieb:
> Selbstverständlich nicht – aber einen auf Deutsch geschriebenen Text
> muss man vorher auch richtig verstehen können, was ich explizit vor so
> einem Reference Manual empfehle, dann erübrigen sich solche und ähnliche
> unsinnigen Unterstellungen.

Welchen meinst du?
Für mich klingen deine Post mach "Ne! Bloß keine Libs benutzen!" (inkl. 
Arduino-Bashing).

Gregor J. schrieb:
> Wenn Du meine Aussage verstanden hättest, bräuchtest Du solche absurden
> Sachen nicht zu schreiben.

Wenche du auch immer meinst.
Andere haben sie wohl auchb "falsch" verstanden...
Ob das dann wirklich an denjenigen liegt, die deine Posts kommentiert 
haben?

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Rahul D. schrieb:
> Welchen meinst du?
> Für mich klingen deine Post mach "Ne! Bloß keine Libs benutzen!" (inkl.
> Arduino-Bashing).

Dein Klingen in den Ohren ist leider falsch. Das ist nur eine weitere 
Bestätigung, dass Du meine auf Deutsch geschriebene Aussage nicht 
verstanden hast. Und bitte nicht vergessen: immer alles, was der 
Siliziumgott gegeben hat, auch schön weiternutzen, aber in der richtigen 
Priorisierung und Reihenfolge.

von Rahul D. (rahul)


Lesenswert?

Gregor J. schrieb:
> Dein Klingen in den Ohren ist leider falsch. Das ist nur eine weitere
> Bestätigung, dass Du meine auf Deutsch geschriebene Aussage nicht
> verstanden hast. Und bitte nicht vergessen: immer alles, was der
> Siliziumgott gegeben hat, auch schön weiternutzen, aber in der richtigen
> Priorisierung und Reihenfolge.

Post, der unter Kategorie "Du hast Recht, und ich meine Ruhe." fallen.
Ganz schön arrogant.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Lesenswert?

Nochmal an alle Manuals-, Registerphobiker oder -allergiker: ohne die 
Reference Manuals (ja, es gibt quasi für jeden µC eins) lesen, verstehen 
und gebrauchen wird man sich in der STM32-Welt nur peripher und 
oberflächlich auskennen und sich dort gewissermaßen wie auf einem 
Arduinotrip befinden oder auf so einer Art Welle schwimmen. Die Kenntnis 
der Hardware ist das A und O, mit weichgespülten Methoden wie „Ach, 
bitte bloß keine Register oder Datenblätter!” aus der Arduinojüngerszene 
wird man hier immer im Sandkasten bleiben – aber in gewisser Weise finde 
ich das auch gerecht und gut so, dass es so ist.

: Bearbeitet durch User
von Terence S. (takeshi)


Lesenswert?

Danke erst einmal für die Antworten. Der Timer läuft nun, die PWM wird 
generiert. Es fehlte tatsächlich der Befehl zum Starten des Timers.
1
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);

Vor einigen Jahren hatte ich schon mal einen STM32 programmiert und auch 
PWMs generiert, aber so genau konnte ich mich nicht mehr dran erinnern 
und den Teil habe ich beim Vergleich mit dem alten Projekt einfach 
übersehen.

Wastl schrieb:
> Was hindert dich daran, dein *.ioc File zu posten? Ist deine
> Kreation so geheim dass man sie nicht nachvollziehen darf?
>
> Ein komplettes Projekt (ohne *.obj und sonstigen Debug-Ballast)
> wäre noch hilfreicher ...

Mich hindert gar nichts daran, die ioc-Datei oder das ganze Projekt zu 
posten, das ist abgesehen von dem Timer sowieso leer. Ich hielt es nur 
für sinnvoller, Screenshots der relevanten Konfiguration zu posten, weil 
da jeder direkt reinschauen kann, selbst ohne installierte IDE. Deshalb 
schrieb ich doch, wenn noch etwas benötigt wird, einfach fragen. Aber 
jetzt geht es ja.

Wastl schrieb:
> Dafür gibt es mundgerecht in den HAL- und LL-Libs einfache
> Aufrufe - wiederum ohne Register-Adressen oder -Namen sondern
> als sinnbringende Makros. Siehe Anhang.

Danke, das war ein sehr guter Hinweis, denn mir war nicht bekannt, dass 
es neben den HAL- auch die LL-Bibliotheken gibt. Bei Recherchen im Netz 
hatte ich immer nur gefunden, dass ST heute nur noch HAL vorsieht und 
die LL-Bibliotheken seit Jahren nicht mehr weiterentwickelt werden. Aus 
diesem Grund habe ich ST-Mikrocontroller bisher kaum eingesetzt, weil 
der ganze HAL-Mist schnarchlangsam ist und ich nie verstehe, was ich da 
wirklich gerade mache. Normalerweise programmiere ich deshalb mit 
direkten Registerzugriffen. Die LL-Bibliotheken sehen aber ziemlich 
übersichtlich aus, damit lässt sich arbeiten.

Und die Diskussion hier noch ein wenig anzuheizen: Wenn ich ein 
Hardwaremodul richtig verwenden möchte, muss ich genau wissen, wie es 
funktioniert und jeden Teil konfigurieren können. Das Manual erklärt, 
wie das Modul aufgebaut ist, was es kann und welchen Einfluss Register 
haben bzw. welche Informationen sie enthalten. Die Erklärung enthält 
keinerlei Bezug zu den Funktionen in den Bibliotheken. Das Einfachste 
ist daher, direkt auf die Register zuzugreifen. Andernfalls muss ich mir 
erst anschauen, was ich mit den Registern tun muss und dann selbst in 
den Bibliotheken stöbern, welche Funktion das tut, was ich möchte. Das 
ist schon mal aufwendiger und im schlimmsten Fall langsamer. Ohne eigene 
Dokumentation ist der Programmcode mit den vorgegebenen Funktionen 
natürlich leichter verständlich, was gerade dann nützlich ist, wenn 
mehrere an einem Projekt arbeiten. Aber gut dokumentiert ist der Code 
mit direkten Registerzugriffen ebenfalls gut verständlich und sogar 
besser bearbeitbar, weil wieder eine direkte Arbeit mit dem Manual 
möglich ist. Ich muss nicht raten oder lange nachschauen, wie nun die 
andere Funktion heißt, die ich jetzt brauche. Und wer ein wenig mit 
einem Controller gearbeitet hat und die Module kennt, versteht auch den 
Code mit direkten Zugriffen.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Wastl schrieb:

> Man kann heutztage praktisch alle Register eines Controllers mittels
> HAL-Lib- oder LL-Lib-Funktionen und -Makros steuern ohne jemals ein
> Controller-Register genannt oder adressiert haben zu müssen.

Ja. Wenn aber irgendein verschissenes nötiges Bit noch nicht gesetzt 
ist, was dann? Dann muß man erstmal herausfinden, welches das ist. Dazu 
muß man halt die Hardware kennen, dann kann man das herausfinden. 
Klappert man "einfach" im Debugger alle relevanten Register ab. Das 
können schon mal eine ganze Menge sein und man muss die Zusammenhänge 
der Hardware verstehen, um überhaupt erstmal rauszufinden, welche das 
alles sein könnten.

Kennt man das Bit erstmal, ist es dann nur noch mittelmäßiger Aufwand, 
die zuständige HAL-Routine zu ermitteln. Und die dann aufzurufen, kostet 
am Ende tatsächlich nur noch ein kühles Arschrunzeln.

Das Problem ist halt: diese verschissene HAL sagt dir an keine Stelle, 
dass dieses Bit von der Initialisierung nicht mit abgedeckt ist, sondern 
zur Laufzeit explizit zusätzlich zur generierten Initialisierung 
gesetzt werden muss, damit die Sache läuft.

Und (u.a. deswegen) ist sowas wie die HAL ein ziemlicher Berg 
SCHEISSE.

von Gregor J. (Firma: Jasinski) (gregor_jasinski)


Angehängte Dateien:

Lesenswert?

Terence S. schrieb:
> Normalerweise programmiere ich deshalb mit
> direkten Registerzugriffen. Die LL-Bibliotheken sehen aber ziemlich
> übersichtlich aus, damit lässt sich arbeiten.

Mit den LL-Befehlen ist man de facto auf der Registerebene und die nutze 
ich zu 90-95% auch, der Rest sind eigene Macros, die ich dann ähnlich 
wie die LL-Macros gestaltet habe und auch so nutzen kann, weil die 
LL-Macros nicht immer alles abdecken, manchmal aber auch fehlerhaft oder 
unsinnig geschrieben sein können – man sollte also wenigstens einmal mit 
der Maus in der IDE nachschauen, wie die LL-Macros aussehen und was sie 
tatsächlich so im Hintergrund tun. Manchmal offenbaren sie eben die 
Unfähigkeit der Personen, die diese für die Allgemeinheit geschrieben 
haben – diese Unfähigkeit offenbart sich beispielsweise sehr gut in der 
RTC-Domain (Real-Time-Clock). Um die LL für die jeweilige Peripherie 
richtig nutzen zu können, muss man das auch explizit so für die 
Codegenerierung umschalten – meistens muss man dabei wenigstens eine 
Peripherie auf HAL-Ebene lassen, z.B. die RCC-Domain (Screenshot im 
Anhang), damit die aufgeblähte Moloch-IDE später beim Build fehlerfrei 
funktioniert (es war zumindest in den früheren IDE-Versionen so 
fehlerbehaftet konstruiert).

So, und nun dürfen sich hier im Thread die Reference-Manual-Verweigerer 
und Registerphobiker wieder zusammentun, sich gegenseitig stärken und 
dazu ermuntern, der Welt zu zeigen, wie man die STM32 – ohne jemals den 
Registeraufbau im Reference Manual gesehen zu haben – benutzen kann. 
Manchmal hilft auch hoffen und beten, dass das, was da im HAL so für die 
breite Masse zusammengedichtet wurde, auch immer ordnungsgemäß 
funktioniert. Und falls der Sand im Sandkasten nicht mehr so schön ist, 
darf Papi neuen holen und den verbrauchten austauschen, damit es wieder 
Spaß macht, sich eine ordentliche Sandburg zu bauen oder damit einfach 
auch mal zu bewerfen oder zu zeigen, wer der größte König im Sandkasten 
ist. Hält alles übrigens maximal so lange bis der nächste Regen kommt.

von Terence S. (takeshi)


Lesenswert?

@Gregor J.: Danke, damit erscheint der STM32 immer besser sinnvoll 
benutzbar zu sein. Das alles hat mir wirklich sehr weitergeholfen.

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.