Hallöchen,
nachdem ich mich seit zwei Wochen gemütlich in die STM32-Reihe
einarbeite und dachte, ich hätte die Timer-Einstellung verstanden, gibt
es nun ein Problem:
Ziel: PA6 per Timer-Update-Interrupt von TIM3 zu toggeln
Das Problem: er toggelt zwar wunderbar, allerdings entspricht die
Frequenz (7,92Hz) nicht der von mir erwarteten Frequenz von 50Hz.
Übersetzt wurde mit -DHSE_VALUE=8000000, den Rest der
PLL-Initialisierung überlasse ich ohne weitere Veränderungen
SystemInit(). Der Systemtakt sollte also 168MHz betragen. Externer Quarz
läuft auch mit 8MHz (gemesen).
Was mich besonders wundert ist der "krumme" Wert - man vergisst ja gerne
mal einen Vorteiler oder so etwas - aber hier bin ich ratlos.
Dasselbe Ergebnis gibt es übrigens mit einem zweiten Discovery-Kit.
Hier der relevante Code (wie gesagt: er macht, was er soll - nur eben
nicht mit gewünschter Frequenz):
Hallo,
ich musste in system_stm32f4xx.c PLL_M von 25 auf 8 stellen (weil der
Quarz auf dem Discovery 8 MHz hat).
Dann stellst du noch Period auf 99 (glaube ich).
Danach sollte PA6 mit 50 Hz getoggelt werden (25 mal pro Sekunde high
und low).
Ich hoffe, das hilft dir weiter.
Thomas
Wie sieht denn der APB1 Prescaler aus (steht wahrscheinlich in den
Comments der system_stm32f4xx.c) ? Der Timer wird ja von APB1 mit seinem
Takt versorgt.
Bei mir war er standardmäßig auf 4 gesetzt, sodass du mit diesen
Einstellungen auf 12.5 Hz kommen müsstest.
Das wäre schonmal etwas näher am gemessenen Wert.
> den Rest der PLL-Initialisierung überlasse ich ohne weitere Veränderungen> SystemInit()
Dann guck da doch mal rein und setz nen Haltepunkt rein beim debuggen.
Dann überprüfst du einfach mal was in die ganzen PLL Register
reingeschrieben wird bzw. was drin steht und schaust mal inst Datenblatt
und rechnest aus mit wieviel er nun läuft.
Thomas W. schrieb:> Hallo,>> ich musste in system_stm32f4xx.c PLL_M von 25 auf 8 stellen (weil der> Quarz auf dem Discovery 8 MHz hat).
In der stm32f4xx.h findet sich das hier. Daher dachte ich, mit HSE_VALUE
wäre alles erschlagen.
1
/**
2
* @brief In the following line adjust the value of External High Speed oscillator (HSE)
3
used in your application
4
5
Tip: To avoid modifying this file each time you need to use different HSE, you
6
can define the HSE value in your toolchain compiler preprocessor.
7
*/
8
9
#if !defined (HSE_VALUE)
10
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
11
#endif /* HSE_VALUE */
AVerr schrieb:> Wie sieht denn der APB1 Prescaler aus (steht wahrscheinlich in den> Comments der system_stm32f4xx.c) ? Der Timer wird ja von APB1 mit seinem> Takt versorgt.> Bei mir war er standardmäßig auf 4 gesetzt, sodass du mit diesen> Einstellungen auf 12.5 Hz kommen müsstest.> Das wäre schonmal etwas näher am gemessenen Wert.
Ja, hier steht auch eine 4.
Also ist der APB1 (42MHz) wirklich der Takt, mit dem der Timer zählt. In
der Referenz steht in den Schaubildern nämlich immer nur etwas von
"CK_INT", wobei nirgends erklärt wird, woher der genau kommt (oder ich
habs übersehen - die Referenz ist ja nicht gerade klein ;-).
Ich hatte schon vermutet, dass APB1 nur für den Bus zuständig ist und
der Zähler direkt die Systemclock erhält.
Ok, dann müsste ich bei 12,5Hz landen. Bleibt nur noch eine "winzige
Differenz" ;-)
Chris D.
Steht im Datenblatt im Block Diagramm auf Seite 18 (mußt halt gucken an
welchem Bus die komponente hängt und am Bus steht noch die Maximale
Taktfrequenz die du einhalten mußt).
oder auf Seite 85 in der Referenz
Setz doch mal nen Haltepunkt in die Funktion und guck was wirklich drin
steht bzw. ob die Funktion überhaupt aufgerufen wird.
Das Problem ist zumindest teilweise gelöst.
Also:
Taktquelle für den Zähler ist die Frequenz von APB1 (42MHz).
Diese schicke ich durch den Vorteiler, um auf die 10kHz Zählfrequenz zu
gelangen.
Zusätzlich muss - wie Thomas oben anmerkte - tatsächlich PLL_M von 25
auf 8 geändert werden. Also Pustekuchen mit "nur HSE_VALUE" ändern ...
Meine 7,92Hz ergaben sich aus dem fehlenden Faktor 4 (168->42MHz) mal
dem Faktor 25/8 und meiner etwas zu hoch gesetzten Timer period - er
zählt ja von 0 an, also ist 99 korrekt, nicht 100.
Immerhin gibt er jetzt exakt 100Hz raus.
Jetzt muss ich nur noch irgendwo einen Faktor 1/2 finden, um auf meine
erwarteten 50Hz zu kommen ;-)
Es hilft nichts, ich muss mir wohl doch erstmal die genauen Abläufe zur
Takterzeugung reinziehen.
Ich dachte eigentlich, die Standard-Lib wäre dazu da, Einsteigern genau
das abzunehmen ... falsch gedacht ;-)
Chris D.
Uwe schrieb:> Steht im Datenblatt im Block Diagramm auf Seite 18 (mußt halt gucken an> welchem Bus die komponente hängt und am Bus steht noch die Maximale> Taktfrequenz die du einhalten mußt).> oder auf Seite 85 in der Referenz
Ja, genau, so ein Schema hab ich gesucht - danke :-)
Am Anfang sieht man den Wald vor lauter Bäumen nicht.
> Setz doch mal nen Haltepunkt in die Funktion und guck was wirklich drin> steht bzw. ob die Funktion überhaupt aufgerufen wird.
Ja, aufgerufen wird sie (habe da gerade PLL_M geändert).
Der Debugger läuft hier leider noch nicht (ich hab hier CodeSourcery),
das kommt als nächstes :-/
Chris D.
Chris D. schrieb:> Also ist der APB1 (42MHz) wirklich der Takt, mit dem der Timer zählt.
Nein, das ist laut Datenblatt der maximale Interfacetakt. Der maximale
Timertakt entspricht dem Doppelten (84 MHz).
Nur die Timer 1,8,9,10 und 11 zählen mit 168 MHz.
Im kästchen auf Seite 85 in der Referenz ist noch einmal eine extra
Verzweigung drin für APBx Komponenten und APBx Timer bei den Timern
steht drin
if APB Prescaler=1 dann Clock x 1
ansonsten Clock x 2
Das heist wenn du 4 als Prescaler hast wird der Takt nur für die Timer
noch mal verdoppelt ! Also 84MHz statt 42.
Uwe schrieb:> Im kästchen auf Seite 85 in der Referenz ist noch einmal eine extra> Verzweigung drin für APBx Komponenten und APBx Timer bei den Timern> steht drin> if APB Prescaler=1 dann Clock x 1> ansonsten Clock x 2> Das heist wenn du 4 als Prescaler hast wird der Takt nur für die Timer> noch mal verdoppelt ! Also 84MHz statt 42.
Ja, vielen Dank.
Ich hab's gerade auch im Schaubild festgestellt - das erklärt dann auch
die 100Hz anstatt der 50Hz :-)
Problem ist also gelöst - vielen Dank an alle!
Ach, eins fällt mir noch ein (bevor ich mich durch die Takterzeugung
wühle):
Es gibt nicht zufällig irgendwo diese Takte als fertig berechnete
Defines/Variablen in der Standard-Lib?
Chris D.
Chris D. schrieb:> Es gibt nicht zufällig irgendwo diese Takte als fertig berechnete> Defines/Variablen in der Standard-Lib?
Bei ST.com gibt es ein Excelfile zur ClocK-Konfiguration, das erzeugt
auch die system_stm32f4xx.c.
Ist schick gemacht und visualisiert auch schön die Clocks.
ReinerL
Chris D. schrieb:> Zusätzlich muss - wie Thomas oben anmerkte - tatsächlich PLL_M von 25> auf 8 geändert werden. Also Pustekuchen mit "nur HSE_VALUE" ändern ...
HSE_VALUE definiert nur die vorhandene Quarzfrequenz. Aber woher soll
die system_init wissen, wie schnell Dein µC wirklich rennen soll. Die
168MHz sind nur das Maximum, ist aber nicht immer notwendig. Also nimmt
man dafür die PLL_ Werte zur Einstellung.
Das Excelfile vomn STM ist gut, wenn man es einmal verstanden hat.
Danke für den Hinweis auf die Excel-Datei - das erleichtert es doch
sehr.
Aber jetzt blicke ich schon ganz gut durch die Takterzeugung durch :-)
Wenn heute ich mal Leerlauf habe, werde ich mal den Debugger einrichten
(unter Ubuntu). Da gibt es dann sicher auch wieder Fragen ;-)
Chris D.