Ich möchte mit einem der Timer des STM32F1 eine veränderliche Frequenz
erzeugen. (Ich möchte hingegen keine PWM, also ein Signal fester
Frequenz aber mit veränderlichem Duty-Cycle erzeugen).
Nach längerer Lektüre des Reference-Manuals meine ich folgendes
feststellen zu können:
1. Bei einem Overflow und dem Update-Event des Timer (also dem erreichen
des in das Auto-Reload-Register geladenen Wertes) kann ein Interrupt
ausgelöst werden. Es kann aber hardwaremäßig kein Pin getoggelt werden
(abgesehen von Code in der Int-Routine der das tun könnte, aber das wäre
eben nicht per Hardware).
2. Beim erreichen des Wertes in einem der Compare Register kann
hardwaremäßig ein Pin getoggelt werden (OCx).
Da ich, wiegesagt, eine veränderliche Frequenz (mit festem Duty-Cycle
von 50%) erzeugen möchte und das, wenn möglich per Hardware des Timers,
bleibt mir also scheinbar nur die Möglichkeit eins der Compare-Register
auf die Hälfte der Periodendauer und das Autoreload-Register auf die
Periodendauer einzustellen und beim Compare den OCx zu toggeln.
Das aber würde bedeuten, das bei einer Frequenzänderung immer beide
Register, sowohl das Compare-Register als auch das Auto-Reload-Register
geändert werden müssen.
Ich frage mich nun, ob ich etwas übersehen habe oder ob es tatsächlich
keine andere Möglichkeit gibt.
Hat jemand Informationen oder Tips dazu?
Blumenpol schrieb:> Es kann aber hardwaremäßig kein Pin getoggelt werden> (abgesehen von Code in der Int-Routine der das tun könnte, aber das wäre> eben nicht per Hardware).
Das ist wahr, aber was spricht dagegen, es mit einer Zeile im IRQ
Handler zu tun ?
Blumenpol schrieb:> bleibt mir also scheinbar nur die Möglichkeit eins der Compare-Register> auf die Hälfte der Periodendauer und das Autoreload-Register auf die> Periodendauer einzustellen und beim Compare den OCx zu toggeln.
Ja, auch richtig. Im Centered Mode mit Hoch- und runterzählendem Timer
hast du vermutlich das schönste Signal. Warum willst du das nicht machen
?
Es gäbe noch die Möglichkeit, den frequenzbestimmenden Timer mit kurzem
OC laufen zu lassen und ein externes Flipflop sorgt dann für die 50%
duty. Dazu muss der Timer mit dem doppelten der gewünschten Frequenz
laufen.
>Das ist wahr, aber was spricht dagegen, es mit einer Zeile im IRQ Handler zu tun
?
Zunächst nichts.
Ich will die vorhandenen Möglichkeiten nutzen bzw. wissen ob es sie
gibt. Zur Erzeugung einer PWM lasse ich die Hardware den Ausgangspin
toggeln weil sie es kann. Sonst, im allgemeinen, aus keinem besonderen
Grund.
Wenn ich nur ein Register zu ändern bräuchte um die Frequenz zu
einzustellen, dann würde ich das tun, anstatt zwei Register zu ändern.
Ich bin mir nur nicht ganz sicher ob das Ergebnis meiner Lektüre richtig
und vollständig ist. Deswegen hätte ich gerne entweder eine Bestätigung
oder einer Widerlegung gehabt. Das wäre nett.
Also, es geht doch.
Man muss nur den Compare Wert auf 0 setzen und dafür einen Pin-Toggle
programmieren. Über die Periode, also das Auto-Reload-Register bestimmt
man dann die halbe Periodendauer.
hi,
könntest du evtl. die wesentlichen Quelltext auszüge zu deiner
Timerconfig und deiner IRQ Routine mal posten?
Ich möchte auch eine variable Frequenz erzeugen und hatte es so
verstanden, das es an PC6 mittels Timer3 möglich ist.
Hardwaremässig hinbekommen habe ich es aber nicht.
Momentan sieht es bei mir so aus (Auszüge...mein timer3 läuft mit 30MHz
und auch die IRQ Routine wird angesprungen)
Eine veränderbare Frequenz erzeuge ich, indem ich die Periode ändere.
Aber ist das so im Sinne des Erfinders? Mein TIM_Pulse aka CCR1_Val hat
überhaupt keinen Einfluss(was ich eigentlich erwartet hätte)
Hardwaremässig den Pin toggeln zu lassen habe ich auch nicht
hinbekommen, obwohl ich das Datenblatt so verstanden habe das es gehen
sollte:
1. Select the counter clock (internal, external, prescaler).
2. Write the desired data in the TIMx_ARR and TIMx_CCRx registers.
3. Set the CCxIE and/or CCxDE bits if an interrupt and/or a DMA request
is to be
generated.
4. Select the output mode. For example, you must write OCxM=011,
OCxPE=0, CCxP=0
and CCxE=1 to toggle OCx output pin when CNT matches CCRx, CCRx preload
is not
used, OCx is enabled and active high.
5. Enable the counter by setting the CEN bit in the TIMx_CR1 register.
Hat jemand eine Idee, was ich da verpeile?
Eine änderbare Frequenz kann ich damit schon erzeugen, aber ich glaube,
das ich das recht umständlich mache und nicht so wie es eigentlich
gedacht ist
Wenn ich den Alternate Function Mode aktiviere, dann ist der Pin doch an
Tim3 gekoppelt und wird als Output/input verwendet, oder? Habe da wie
gesagt rumprobiert, aber es lief nie so wie ich es wollte(bzw. es ist
gar nix passiert im AF Mode)
A. B. schrieb:> Wenn ich den Alternate Function Mode aktiviere, dann ist der Pin doch an> Tim3 gekoppelt und wird als Output/input verwendet, oder?
Da hast vermutlich vergessen, die AFIO Clock zu aktivieren:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);