Forum: Mikrocontroller und Digitale Elektronik STM32F103 TIM1 PWM Frequenz stimmt nicht


von Stm M. (stmfresser)


Lesenswert?

Hallo,

auf einem STM32F103 High Density Board ohne externen Quarz möchte ich 
eine PWM mit 15kHz generieren. Es geht zwar aber, seltsamerweise beträgt 
die PWM Frequenz am Oszi immer die Hälfte meiner berechneten Frequenz.

Systemtakt Einstellung auf 48MHz.
1
  RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12); // 48MHz
2
  RCC_PLLCmd(ENABLE);
3
4
  while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {
5
  }
6
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
7
8
  /* Set HCLK, PCLK1, and PCLK2 to SCLK (these are default */
9
  RCC_HCLKConfig(RCC_SYSCLK_Div1); // 48 MHz
10
  RCC_PCLK1Config(RCC_HCLK_Div2);  // APB1 24MHz, max 36MHz
11
  RCC_PCLK2Config(RCC_HCLK_Div1);  // APB2 48MHz

danach die gesetzten Werte geprüft
1
trace_printf("SYSCLK_Frequency: %u \n", clocks.SYSCLK_Frequency);
2
trace_printf("PCLK1_Frequency: %u \n", clocks.PCLK1_Frequency);
3
trace_printf("PCLK2_Frequency: %u \n", clocks.PCLK2_Frequency);
4
trace_printf("ADCCLK_Frequency: %u \n", clocks.ADCCLK_Frequency);
5
6
SYSCLK_Frequency: 48000000 
7
PCLK1_Frequency: 24000000 
8
PCLK2_Frequency: 48000000
9
ADCCLK_Frequency: 24000000

mit dieser PWM Initialisierung beträgt die PWM Frequenz 15kHz wie 
gewünscht. Wenn ich die Werte in der Formel einsetze, kommt 30kHz raus. 
Beträgt der APB2 Takt etwa 24MHz?
1
/* TIM1 clock enable APB2 = 48MHz */
2
  /* 15kHz PWM_fr = TIM_CLK_fr / (Prescaler + 1) / (Period + 1)  TIM_CLK_fr = 48MHz */
3
4
  /* TIM1 clock enable APB2 = 48MHz */
5
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
6
7
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
8
  TIM_OCInitTypeDef TIM_OCInitStructure;
9
10
  /* Initialize basic structures to default */
11
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
12
  TIM_OCStructInit(&TIM_OCInitStructure);
13
14
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
15
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
16
  TIM_TimeBaseStructure.TIM_Period = 1600 - 1;
17
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
18
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
19
20
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

von m.n. (Gast)


Lesenswert?

Stm M. schrieb:
> Es geht zwar aber, seltsamerweise beträgt
> die PWM Frequenz am Oszi immer die Hälfte meiner berechneten Frequenz.

Du berechnest das Intervall bis zur nächsten Änderung des Ausgangs. Da 
man zur Frequenzerzeugung zwei diese Intervalle braucht, ergibt sich die 
doppelte Periodendauer oder eben die halbe Frequenz.

TIM_TimeBaseStructure.TIM_Period = 1600/2 - 1;

von Mike R. (thesealion)


Lesenswert?

Wie erzeugst du denn deine PWM?

Bisher hast du hier nur die Initialisierung des Timers gezeigt, aber 
nicht, wie das Signal dann an die Außenwelt gelangen soll.

von Stm M. (stmfresser)


Lesenswert?

Danke für die Antworten,

es lag an TIM_CounterMode_CenterAligned1. Wenn ich den counter mode auf 
TIM_CounterMode_Up setze, bekomme ich 30kHz.

von m.n. (Gast)


Lesenswert?

Stm M. schrieb:
> es lag an TIM_CounterMode_CenterAligned1. Wenn ich den counter mode auf
> TIM_CounterMode_Up setze, bekomme ich 30kHz.

Wolltest Du nicht 15 kHz? ;-)

von aSma>> (Gast)


Lesenswert?

Stm M. schrieb:
> TIM_TimeBaseStructure.TIM_CounterMode =
> TIM_CounterMode_CenterAligned1;

Das ist des Rätsels Lösung. Guck mal ins Referenz Manual.

m.n. hat es erkannt.

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.