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)
1 | void TIM3_IRQHandler(void) |
2 | { |
3 | if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) |
4 | { |
5 | TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); |
6 | GPIO_ToggleBits(GPIOC, GPIO_Pin_6); |
7 | } |
8 | } |
1 | void init(void){ |
2 | |
3 | GPIO_InitTypeDef GPIO_InitStructure; |
4 | TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; |
5 | TIM_OCInitTypeDef TIM_OCInitStructure; |
6 | |
7 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Tim3 Clock */ |
8 | RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOC, ENABLE); |
9 | //GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); /* PC6 TIM3 Chann */ |
10 | |
11 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; |
12 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; |
13 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
14 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; |
15 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
16 | GPIO_Init(GPIOC, &GPIO_InitStructure); |
17 | |
18 | |
19 | /* |
20 | TIM3 Config siehe auch STM32F2xx_Clock_Configuration_V1.1.0.xls |
21 | TIM3CLK = 30 MHz, Prescaler = 29, TIM3 counter clock = 1MHz |
22 | */ |
23 | |
24 | TIM_TimeBaseStructure.TIM_Period = 10; |
25 | TIM_TimeBaseStructure.TIM_Prescaler = 29; |
26 | TIM_TimeBaseStructure.TIM_ClockDivision = 0; |
27 | TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; |
28 | TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); |
29 | |
30 | /* Output Compare Active Mode configuration: Channel1 */ |
31 | TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active; |
32 | TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; |
33 | TIM_OCInitStructure.TIM_Pulse = 0;//CCR1_Val; |
34 | TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; |
35 | TIM_OC1Init(TIM3, &TIM_OCInitStructure); |
36 | |
37 | TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); |
38 | //TIM_ARRPreloadConfig(TIM3,ENABLE); |
39 | TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); |
40 | } |
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);
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.