Liebe Forenteilnehmer,
ich möchte die Timer auf meinem STM32F4-Discovery Board nutzen,
um Pin PC6 zu toggeln. Aus Lerngründen soll das explizit über
den Output Compare Modus passieren.
Das klappt auch alles wunderbar, wenn ich TIM3 dafür verwende.
Sobald ich jedoch TIM3 durch TIM8 ersetze kommt kein Signal mehr
am Pin PC6 an.
Hier mein nicht funktionierender Code (für TIM8):
Wenn ich in obigem Code alle "8"en durch "3"en ersetze und
zusätzlich den Teilstring "RCC_APB1" durch "RCC_APB2" ersetze,
funktioniert der Code und PC6 toggelt mit 2,5Hz.
Habt Ihr eine Idee?
Wo ist mein Denkfehler?
Worin unterscheidet sich TIM3 von TIM8 in Sachen Output Compare?
Viele Grüße
Igel1
Hallo Andreas,
ich bin noch totaler Anfänger, deshalb muss meine Idee nicht stimmen.
Falls das zutrifft, bitte den Kommentar einfach überlesen.
Ich arbeite mich im Moment ein wenig in den STM32F411 ein. Dieser hat
laut Datenblatt und meinem Verständnis gar keinen Timer 8.
Könnte das dein Problem sein?
Viele Grüße
dochgast
dochgast schrieb:> Hallo Andreas,> ich bin noch totaler Anfänger, deshalb muss meine Idee nicht stimmen.> Falls das zutrifft, bitte den Kommentar einfach überlesen.> Ich arbeite mich im Moment ein wenig in den STM32F411 ein. Dieser hat> laut Datenblatt und meinem Verständnis gar keinen Timer 8.> Könnte das dein Problem sein?>> Viele Grüße> dochgast
nachdem sein code richtig compiliert wurde muss er wohl einen tim8
haben.
aber ohne genaue bezeichnung ist das ein ratespiel.
Der Pin muss wissen an welcher AF er hängt.
Beim STM32F446 ist z.B. Timer 1 AF2 und Timer 3 AF3 ...
Master output enable brauchst du nur wenn du andere Timer syncronisieren
willst.
Hans-Georg L. schrieb:> Der Pin muss wissen an welcher AF er hängt.> Beim STM32F446 ist z.B. Timer 1 AF2 und Timer 3 AF3 ...
Dachte auch erst es würde daran liegen aber Martin hat glaube ich recht:
Martin schrieb:> du Musst das MOE Bit setzen (Master output enable), auch bei TIM1 ist> das so
weil Timer 1 und 8 "Advanced Timer" sind muss man das MOE Bit zwingend
setzen, sonst tut sich am Ausgang nichts. In Tabelle 94. im Handbuch
(RM0090) gibt es noch eine Übersicht wie welches Bit den Ausgang
beeinflusst.
dochgast schrieb:
> Ich arbeite mich im Moment ein wenig in den STM32F411 ein.> Dieser hat laut Datenblatt und meinem Verständnis gar keinen Timer 8.> Könnte das dein Problem sein?
Das ist suess :)
Ich hatte vor meiner Frage natürlich das Reference Manual und auch das
Internet befragt. Wenn mir dann nicht aufgefallen wäre, dass mein Chip
gar keinen TIM8 hat, so hätte ich wirklich ein dickes Brett vorm Kopf
gehabt. Aber auch das soll schon einmal vorkommen,
Daher: Danke für Deinen Hinweis.
------------------------------------------------
ziegler schrieb:
> nachdem sein code richtig compiliert wurde muss er wohl einen> tim8 haben. aber ohne genaue bezeichnung ist das ein ratespiel.
Hmmm - ich dachte eigentlich mit meiner Angabe STM32F4-Discovery Board
sei alles gesagt und hatte daher Deine Frage zunächst nicht verstanden.
Aber Du hast natürlich recht: nicht jeder kennt den Chip auf dem
STM32F4-Disco-Board - es ist ein STM32F407VGT6 mit 12 Zylindern und
Einspritzung.
-------------------------------------------------
Martin schrieb:
> du Musst das MOE Bit setzen (Master output enable),> auch bei TIM1 ist das so
Chapeau!!
Du hast den Vogel auf Anhieb abgeschossen!
(ich glaube, so etwas nennt man "Erfahrung" ...)
Nachdem ich das MOE Bit gesetzt hatte, schnurrte die Kiste
sofort wie Schmitz' Katze.
Und für die Nachwelt gibt's den korrigierten, lauffähigen Code:
TIM_CtrlPWMOutputs(TIM8, ENABLE); // Set the Main Output Enable Bit (MOE)
38
// In gratefulness to Martin
39
40
TIM_Cmd(TIM8, ENABLE);
41
}
--------------------------------------------------------
Hans-Georg Lehnard schrieb:
> Der Pin muss wissen an welcher AF er hängt.> Beim STM32F446 ist z.B. Timer 1 AF2 und Timer 3 AF3 ...
Das weiss er durch Aufruf von:
1
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); // Routing TIM8 output to PC6 (P2 , Pin47 on STM32F4disco)
... hattest Du vermutlich überlesen.
> Master output enable brauchst du nur wenn du andere Timer> syncronisieren willst.
Damit liegst Du leider falsch (ich war ebenfalls überrascht ...)
Den Gegenbeweis findest Du als Bild im Anhang.
---------------------------------------------------------
Christopher Johnson schrieb:
> weil Timer 1 und 8 "Advanced Timer" sind muss man das MOE Bit> zwingend setzen, sonst tut sich am Ausgang nichts.> In Tabelle 94. im Handbuch (RM0090) gibt es noch eine Übersicht> wie welches Bit den Ausgang beeinflusst.
Auch dieser Tipp ein Treffer ins Schwarze (sogar mit Refman Verweis!).
Dickes Dankeschön daher auch an Dich!
-----------------------------------------------------------
Viele Grüße und Danke nochmals an alle Helfer für die Mühen -
insbesondere natürlich an Martin und Christopher für die Gold-Tipps.
Igel1
PS:
Und wenn ich hier schon einmal die Profis an der Angel habe:
Habt Ihr vielleicht einen Zusatztipp, wie man dieses Timer-Zeugs
vernünftig debuggt? Am liebsten würde ich per Einzelschritte
die Zustände aller internen "Leitungen" aus den Bildern im
Reference-Manual sehen ...
> Martin schrieb:>> du Musst das MOE Bit setzen (Master output enable),> auch bei TIM1 ist das so>
Hast Recht das ist diese Break Feature womit man die Ausgänge abschalten
kann.
> Andreas schrieb:> Habt Ihr vielleicht einen Zusatztipp, wie man dieses Timer-Zeugs> vernünftig debuggt? Am liebsten würde ich per Einzelschritte> die Zustände aller internen "Leitungen" aus den Bildern im> Reference-Manual sehen ...
Ich schau mir die Timer Register im Debugger an und die Ausgangssignale
auf dem Osci.
Es gibt auch einen Abschnitt "Debug support for timers .." im Reference
Manual habe ich aber noch nicht ausprobiert.
Andreas S. schrieb:> GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); //
Wo kommt diese Funktion her ? bringt bei mir einen Syntax Error.
Und was macht die Funktion wenn ich sie so aufrufe
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM6);
oder
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM8);
Auch hier nochmal der Tipp von mir, sich die Beispiele bspw. der StdLib
bzgl. Timer-PWM anzusehen.
Üblicherweise finden sich diese unter
Project/Peripheral_Examples/TIM_PWM_Output. Dort findet sich bei der
Initialisierung des Timers am Ende so etwas,
1
/* TIM1 counter enable */
2
TIM_Cmd(TIM1, ENABLE);
3
4
/* TIM1 Main Output Enable */
5
TIM_CtrlPWMOutputs(TIM1, ENABLE);
6
7
/* Infinite loop */
8
while (1)
9
{}
was einen hellhörig werden lassen sollte :-)
Ich hatte das Bit übrigens damals auch übersehen ("Break and dead-time
register? Brauch ich nicht.") und kam erst durch das Beispiel darauf
<:-)
Hans-Georg L. schrieb:> Andreas S. schrieb:>>> GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); //>> Wo kommt diese Funktion her ? bringt bei mir einen Syntax Error.
Die ist bspw. in der StdLib enthalten. Du musst den entsprechenden
Header mit #include "stm32f0xx_gpio.h" einbinden (und natürlich die
entsprechenden Sourcen mitkompilieren).
> Und was macht die Funktion wenn ich sie so aufrufe>> GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM6);>> oder>> GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM8);
Damit verknüpfst Du den Pin mit dem entsprechenden internen Modul, also
z.B. mit einem OC-Ausgang eines Timers. Du kannst aber nicht jedes Modul
mit jedem Pin verbinden.
Chris D. schrieb:> Hans-Georg L. schrieb:>> Andreas S. schrieb:>>>>> GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); //>>>> Wo kommt diese Funktion her ? bringt bei mir einen Syntax Error.>> Die ist bspw. in der StdLib enthalten. Du musst den entsprechenden> Header mit #include "stm32f0xx_gpio.h" einbinden (und natürlich die> entsprechenden Sourcen mitkompilieren).>>> Und was macht die Funktion wenn ich sie so aufrufe>>>> GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM6);>>>> oder>>>> GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM8);>> Damit verknüpfst Du den Pin mit dem entsprechenden internen Modul, also> z.B. mit einem OC-Ausgang eines Timers. Du kannst aber nicht jedes Modul> mit jedem Pin verbinden.
Das ist mir schon klar ;-)
Ich wollte nur darauf hinaus das dieses keineswegs eine universelle
Funktion ist wie der Name vermuten lässt ... Timer 6 hat keinen Ausgang,
und PortA pion 6 kann nicht mit Timer8 verbunden werden.
Bei cubemx erzeugten Code gibts nur ein "stm32f4xx_gpio_hal.h" und
keinen "stm32f4xx_gpio.h"
Wenn ich die HAL Version benutze habe ich das gleiche Problem
(ist jetzt ein anderer Pin und ein anderer Timer)
/**TIM5 GPIO Configuration
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM5;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // Richtig
wenn ich den falschen Port benutze
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); // falsch
Wird das vom Compiler nicht angemeckert
Einen Timer der übehaupt keinen OC Ausgang hat wird als Syntax Fehler
erkannt weil es keine definition GPIO_AFx_TIM6; oder TIM7 gibt;
enums für die AF/PIN/Port Kombinationen würden da helfen ...
Das ist noch ein Grund für mich auf c++ und templates um zu steigen ;-)
Chris D. schrieb:
> Üblicherweise finden sich diese unter> Project/Peripheral_Examples/TIM_PWM_Output.> Dort findet sich bei der> Initialisierung des Timers am Ende so etwas,> [...]> was einen hellhörig werden lassen sollte :-)
Ja - diesen Weg gehe ich auch immer - und auch diesmal hatte ich
zunächst in die Peripheral_Examples reingeschaut und dort das OC
Beispiel gut beäugt - nur ist jenes Beispiel halt mit TIM3 realisiert,
der (wie wir inzwischen wissen) kein MOE-Bit benötigt.
Na ja - und an dieser Stelle bin ich dann halt eben in die Falle
getappt.
Aber wofür habe ich Euch? ;-)
Hier im Forum bekommt man von so vielen netten Leuten so geniale Tipps,
da schäme ich mich nicht, nach 2-3h Suche auch mal aufzugeben und hier
um Rat und Tat zu fragen.
Es gilt ja stets:
"Experience is something you don't get until just after you need it"
In diesem Sinne Danke auch an Hans-Georg für seine Debug-Tipps.
Dein Tipp, Hans-Georg, war mir endlich Ansporn genug, mich um die
nicht funktionierende Anzeige der Peripheral Registers in meiner
IDE zu kümmern (ich nutze die "emIDE").
Hier fand ich dann auch tatsächlich einen Hinweis:
http://emide.org/documentation_debugging_registers.html
Letztendlich genügte es, meinen Prozessortyp "STM32F407VG" als
Target Device in den Debugger-Einstellungen meines Projektes zu
hinterlegen. Et voilà - jetzt kann ich mich vor Registern kaum
noch retten ...
(... 20 Minuten später ...)
... allein ich stelle gerade fest, dass der Registerinhalt in meiner
emIDE nicht angezeigt wird (alles 0x00000000) - Mist.
Liegt evtl. daran, dass ich ST-LINKv2 und nicht J-Link nutze.
Anyway - ich wollte sowieso den ST-Linkv2 in J-Link umflashen - mal
sehen, ob's dann funktioniert.
Viele Grüße
Igel1
Andreas S. schrieb:> Chris D. schrieb:>> ... allein ich stelle gerade fest, dass der Registerinhalt in meiner> emIDE nicht angezeigt wird (alles 0x00000000) - Mist.>> Liegt evtl. daran, dass ich ST-LINKv2 und nicht J-Link nutze.> Anyway - ich wollte sowieso den ST-Linkv2 in J-Link umflashen - mal> sehen, ob's dann funktioniert.>
Der Stlink läuft bei mir unter STM AC6 (eclipse) fehl dir vielleicht das
richtige svd File ?
Darin sind die Register und die dazugehörigen Bits mit ihren Adressen
beschrieben ...
Wenn es dir fehlt schau hier:
https://github.com/posborne/cmsis-svd
> Der Stlink läuft bei mir unter STM AC6 (eclipse) fehl> dir vielleicht das richtige svd File ?
Nein, das war's nicht.
Ich mußte tatsächlich meinen ST-Linkv2 in einen J-Link umflashen
und dann noch ein bißchen in den Projekteinstellungen meiner
emIDE rumwurschteln (ohne 100%ig zu verstehen, was ich da tat ..).
Seitdem geht der Programmupload gefühlt mindestens doppelt so
schnell und die Peripheral Register kann ich nun auch sehen.
Besser hätte es gar nicht laufen können - supi.
Viele Grüße
Igel1