STM32F4 Discovery: Hochfrequenter Timerausgang/Clockfrequenz

OP #2787666
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
OP #2813994
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
Gast #2814024
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.
OP #2814107
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
Gast #2814118
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;)
Gast #2814123
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;
#2814156
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)?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren