Forum: Mikrocontroller und Digitale Elektronik STM32F4 Discovery: Hochfrequenter Timerausgang/Clockfrequenz


von Der M. (naeschd)


Lesenswert?

Hallo zusammen,

ich bei gerade dabei mit dem STM32F4 Discovery-Board ein Projekt zu 
verwirklichen um mich so in dem Controller einzulernen...
Ich benötige für mein Projekt ein relativ hochfrequenten Clock, den ich 
mir erzeugen möchte. Bis jetzt habe ich das auf die herkömmliche Weise 
mit einem Timer und Output-Compare gemacht. Jetzt merke ich jedoch, dass 
wenn ich in einen Bereich von ca. 420kHz komme (CCR1-Val < 100), das 
Ganze nicht mehr funktioniert (Der Ausgang wird dann erheblich 
niederfrequenter (ca. 600Hz)).
Anbei mal mein Timercode:

Init:
1
  //local variable definition
2
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
3
  TIM_OCInitTypeDef  TIM_OCInitStructure;
4
  uint16_t PrescalerValue = 0;
5
  NVIC_InitTypeDef NVIC_InitStructure;
6
7
  /* TIM3 clock enable */
8
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
9
10
  /* Enable the TIM3 gloabal Interrupt */
11
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
12
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
13
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
14
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
15
  NVIC_Init(&NVIC_InitStructure);
16
17
    /* Initialize Leds mounted on STM32F4-Discovery board */
18
  STM32F4_Discovery_LEDToggle(LED4);
19
  STM32F4_Discovery_LEDToggle(LED3);
20
21
  /* Turn on LED4, LED3, LED5 and LED6 */
22
  STM32F4_Discovery_LEDToggle(LED4);
23
  STM32F4_Discovery_LEDToggle(LED3);
24
25
26
  /* Compute the prescaler value */
27
  PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 50000000) - 1;
28
29
  /* Time base configuration */
30
  TIM_TimeBaseStructure.TIM_Period = 65535;
31
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
32
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
33
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
34
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
35
36
  /* Prescaler configuration */
37
  TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);
38
39
  /* Output Compare Timing Mode configuration: Channel1 */
40
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
41
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
42
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //CCR1_Val wird an anderer Stelle initialisiert
43
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
44
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
45
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
46
47
  /* TIM Interrupts enable */
48
  TIM_ITConfig(TIM3, TIM_IT_CC1 , ENABLE);
49
50
  /* TIM3 enable counter */
51
  TIM_Cmd(TIM3, ENABLE);


IRQ:
1
void TIM3_IRQHandler(void)
2
{
3
  static uint8_t pending = 0;
4
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
5
  {
6
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
7
  capture = TIM_GetCapture1(TIM3);
8
    TIM_SetCompare1(TIM3, capture + CCR1_Val);
9
  if (pending <= 200)
10
  {
11
    pending++;
12
  }else{
13
    STM32F4_Discovery_LEDToggle(LED5);
14
    TLC_PORT->ODR ^= TLC_GSCLK_PIN;  //Zum Testen den Ausgang toggeln lassen
15
    //TLCdata();
16
  }
17
  }
18
}

Habt ihr eine Idee warum ich mit dieser Konfiguration keinen 
höherfrequenten Takt erzeugen kann? Wenn ja, mit welcher 
Timerkonfiguration kann ich das bewerkstelligen?

Vielen Dank für eure Unterstützung...
Matze

von Der M. (naeschd)


Lesenswert?

Sorry für den Push, aber ich bin leider noch nicht weitergekommen.

Ich wäre schon hochzufrieden wenn mir jemand einen Tipp geben könnte wie 
ich mit dem STM32F4 (auf dem Discovery-Board) eine Frequenz an einem 
Ausgang erstellen könnte, die ca. 3MHz beträgt. Am schönsten wäre 
natürlich eine nicht-Interrupt getriebene Lösung. Aber ich weiß nicht ob 
das überhaupt möglich ist.

Nochmal vielen Dank!
Grüße Matze

von holger (Gast)


Lesenswert?

>Ich wäre schon hochzufrieden wenn mir jemand einen Tipp geben könnte wie
>ich mit dem STM32F4 (auf dem Discovery-Board) eine Frequenz an einem
>Ausgang erstellen könnte, die ca. 3MHz beträgt.

Wie genau muss die Frequenz sein?
Idee: SPI Modul mit DMA und Circular Mode ohne Memory Increment.
Irgendwas senden und einfach SCK abgreifen.

von Der M. (naeschd)


Lesenswert?

Hi!

Danke für deine Antwort. Das Signal muss ein ganz normaler Rechteck sein 
mit Duty cycle 50%. Also ein ganz normaler Rechteck. Die Frequenz ist 
einigermaßen variabel, sollte aber zumindest höher als 2 MHz sein.
Danke für deine Idee. Könntest du da noch genauer eingehen? Also nicht 
im Detail. Circular Mode heißt zyklisch senden oder? Und was bedeutet 
Memory Increment?

Danke nochmal!
Grüße
Mathias

von holger (Gast)


Lesenswert?

>Circular Mode heißt zyklisch senden oder?

Ja.

> Und was bedeutet Memory Increment?

Ohne Increment sendest du immer nur einen Wert aus einer
festen Adresse ohne die Speicheradresse für das DMA weiter zu zählen.
Also irgendeine Variable anlegen und deren Adresse für das DMA
eintragen. Was da drin steht ist für deinen Zweck egal.

Ob das so klappt müsste ich auch erst mal ausprobieren.
Ist nur so eine Idee;)

von Verwirrter Anfänger (Gast)


Lesenswert?

Ich hab gerade nicht die geistige Kapazität das Problem in deinem Code 
zu suchen aber der unten stehende Code schnipsel gibt mir irgendwas im 
MHz-Bereich aus:
1
  GPIO_InitTypeDef GPIO_InitStructure;
2
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
3
  TIM_OCInitTypeDef TIM_OCInitStructure;
4
5
  // Enable Pin
6
  // TIM3 clock enable
7
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
8
9
  // GPIOB Configuration:  TIM3 CH2 (PB5)
10
  GPIO_InitStructure.GPIO_Pin = CAMERA_EX_CLK;
11
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
13
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
14
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
15
  GPIO_Init(CAMERA_PORT, &GPIO_InitStructure);
16
17
  // Connect TIM3 pins to AF2
18
  GPIO_PinAFConfig(CAMERA_PORT, GPIO_PinSource5, GPIO_AF_TIM3);
19
20
  //  PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 28000000) - 1;
21
  /* Time base configuration */
22
  TIM_TimeBaseStructure.TIM_Period = 1;
23
  TIM_TimeBaseStructure.TIM_Prescaler = 0; //No prescaler
24
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;
25
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
26
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
27
28
  /* PWM1 Mode configuration: Channel2 */
29
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
30
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
31
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
32
  TIM_OCInitStructure.TIM_Pulse = 1;
33
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
34
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
35
36
  TIM_ARRPreloadConfig(TIM3, ENABLE);
37
  /* TIM3 enable counter */
38
  TIM_Cmd(TIM3, ENABLE);
39
  TIM3->CCR2 = 1;

von Jörn (Gast)


Lesenswert?

Hast du noch einen MCO Ausgang am Chip frei?

An dem kannst du u.U. über die PLL deinen Takt einstellen. Such im 
Datenblatt nach "Clock tree" dort ist ein Blockdiagramm dabei.

Gruß Jörn

von Thomas W. (ratos)


Lesenswert?

Der Matze schrieb:
> Ich wäre schon hochzufrieden wenn mir jemand einen Tipp geben könnte wie
> ich mit dem STM32F4 (auf dem Discovery-Board) eine Frequenz an einem
> Ausgang erstellen könnte, die ca. 3MHz beträgt. Am schönsten wäre
> natürlich eine nicht-Interrupt getriebene Lösung. Aber ich weiß nicht ob
> das überhaupt möglich ist.
> Das Signal muss ein ganz normaler Rechteck sein
> mit Duty cycle 50%


Kannst du nicht ganz normal PWM mit TIM_Period=27 (84MHz/3MHz-1) nehmen 
(vorrausgesetzt das Board läuft mit 168 MHz)?

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.