Forum: Mikrocontroller und Digitale Elektronik STM32 mit timer frequenz ausgeben


von Michael L. (nightflyer88)


Lesenswert?

Hallo

Ich mache gerade einige versuche mit dem STM32F4 Discovery. Mit dem 
Timer 2 möchte ich mit einer definierten Frequenz einen Pin toggeln. Mit 
der folgenden initialisierung messe ich am Pin eine Frequenz von 32Hz, 
sollte doch aber 50hz sein ? SystemCoreClock ist 168mhz, die Frequenz 
vom Timer2 sollte dementsprechend 42mhz sein ? was genau mache ich 
falsch ?

1
//***** Setup Timer 2 ******************************
2
    // Takt für Timer 2 einschalten
3
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
4
5
  // Timer2 konfigurieren
6
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
7
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
8
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
9
  TIM_TimeBase_InitStructure.TIM_Period = 42000000/100;
10
  TIM_TimeBase_InitStructure.TIM_Prescaler = 0;
11
  TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
12
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
13
14
  // Timer2 einschalten
15
   TIM_Cmd(TIM2, ENABLE);
16
17
  // Interruptcontroller konfigurieren
18
  NVIC_InitTypeDef NVIC_InitStructure;
19
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
20
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
21
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
22
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
23
  NVIC_Init(&NVIC_InitStructure);

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Michael L. schrieb:
> TIM_TimeBase_InitStructure.TIM_Period = 42000000/100;

Das TIMx_ARR Register ist aber nur 16 bit breit, so das das nicht 
klappen kann. Siehe Abschnitt 18.4.12 im Reference Manual (RM0090).

von Christoph (gizmo)


Lesenswert?

Matthias S. schrieb:
> Das TIMx_ARR Register ist aber nur 16 bit breit, so das das nicht
> klappen kann. Siehe Abschnitt 18.4.12 im Reference Manual (RM0090).

TIM2 und TIM5 sind 32 bit Timer und haben dementsprechend 32 bit 
Register.
Steht auch so im genannten Abschnitt: ARR[31:16] (depending on timers)


Michael L. schrieb:
> SystemCoreClock ist 168mhz, die Frequenz
> vom Timer2 sollte dementsprechend 42mhz sein ? was genau mache ich
> falsch ?

Wenn du bis auf PLL_M und HSE_VALUE in der ST Library sonst nichts 
verändert hast läut APB1 mit 42MHz.
Allerdings wird der Takt speziell für die Timer nochmal verdoppelt auf 
84MHz weil der APB Prescaler ungleich 1 ist (Reference Manual am Ende 
von Abschnitt 7.2).

Jedenfalls setzt du die Periode auf 420000, d.h. mit 84MHz müsste der 
Interrupt alle 0,005 Sekunden auftreten.
Wenn im Interrupt nur ein Pin getoggelt wird sollten eigentlich 100Hz 
herauskommen.

Wieso bei dir 32Hz herauskommen kann ich an deinem Code nicht erkennen 
weil die Interrupt Routine fehlt.

: Bearbeitet durch User
von Michael L. (nightflyer88)


Lesenswert?

irgendwie habe ich den verdacht, dass der System Takt falsch eingestellt 
ist. Mit maximaler geschwindigkeit messe ich 336khz, kann irgendwie 
nicht stimmen... ?!?



1
//***** Setup Timer 2 ******************************
2
    // Takt für Timer 2 einschalten
3
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
4
5
  // Timer2 konfigurieren
6
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
7
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
8
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Down;
9
  TIM_TimeBase_InitStructure.TIM_Period = 1;
10
  TIM_TimeBase_InitStructure.TIM_Prescaler = 0;
11
  TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
12
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
13
14
  // Timer2 einschalten
15
   TIM_Cmd(TIM2, ENABLE);
16
17
  // Interruptcontroller konfigurieren
18
  NVIC_InitTypeDef NVIC_InitStructure;
19
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
20
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
21
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
22
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
23
  NVIC_Init(&NVIC_InitStructure);
24
25
// Timer2 Interrupt
26
void TIM2_IRQHandler(void){
27
    GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
28
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
29
}

von Michael L. (nightflyer88)


Angehängte Dateien:

Lesenswert?

hier in der systemdatei werden die Takte und prescaler eingestellt, ich 
habe da jedoch nichts verstellt..

von Christoph (gizmo)


Lesenswert?

Michael L. schrieb:
> hier in der systemdatei werden die Takte und prescaler eingestellt, ich
> habe da jedoch nichts verstellt..

Dann ist ja klar.

Die Std. Peripheral Library ist Standardmäßig auf einen 25MHz Quarz 
eingestellt.
Auf dem STM32F4 Discovery ist aber ein 8MHz Quarz verbaut.

Du musst in der system_stm32f4xx.c in Zeile 156
1
#define PLL_M 25
auf
1
#define PLL_M 8
ändern.

Dann noch in stm32f4xx.h in Zeile 92
1
#define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
in
1
#define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
ändern.

Dann sollte das funktionieren.

: Bearbeitet durch User
von Michael L. (nightflyer88)


Lesenswert?

super besten dank, funktioniert !

so bekomme ich 10khz:
1
TIM_TimeBase_InitStructure.TIM_Period = 42000000/10000;

aber mehr als 1mhz bekomme ich nicht hin, ist das normal ?

Im kommentar der system_stm32f4xx.c datei steht etwas von APB1 Prescaler 
= 4, was hat es damit auf sich ? Geht da evtl noch mehr als 1Mhz ?
1
  * 5. This file configures the system clock as follows:
2
  *=============================================================================
3
  *=============================================================================
4
  *        Supported STM32F40xx/41xx/427x/437x/429x/439x devices
5
  *-----------------------------------------------------------------------------
6
  *        System Clock source                    | PLL (HSE)
7
  *-----------------------------------------------------------------------------
8
  *        SYSCLK(Hz)                             | 168000000
9
  *-----------------------------------------------------------------------------
10
  *        HCLK(Hz)                               | 168000000
11
  *-----------------------------------------------------------------------------
12
  *        AHB Prescaler                          | 1
13
  *-----------------------------------------------------------------------------
14
  *        APB1 Prescaler                         | 4
15
  *-----------------------------------------------------------------------------
16
  *        APB2 Prescaler                         | 2
17
  *-----------------------------------------------------------------------------

von Michael L. (nightflyer88)


Lesenswert?

Aber läuft der Prozessor jetzt wirklich mit 168Mhz, oder doch nur mit 
8mhz??
Wenn ich die Timer interrupt routine etwas "ausbremse" kommt der 
Prozessor nicht mehr nach, habe dann nur noch 12khz, anstatt 100khz
1
void TIM2_IRQHandler(void){
2
3
  int i;
4
  for (i = 0 ; i < 500 ; i++){
5
  }
6
7
  GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
8
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
9
}


Für ein Prozessor mit 168mhz sollte dass doch kein Problem sein noch 
kurz auf 500 zu zählen, oder täusche ich mich da ??

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Christoph S. schrieb:
> TIM2 und TIM5 sind 32 bit Timer und haben dementsprechend 32 bit
> Register.

Oh ja, da habe ich was mit Timer 3 und 4 verwechselt.

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.