Forum: Mikrocontroller und Digitale Elektronik STM32F4 Timer und GPIO Fragen.


von Peter K. (peterka2000)


Angehängte Dateien:

Lesenswert?

Im Anhang ist mein Code. Dazu hab ich ein Paar Fragen:

1. Wie kann ich für den Timer eine IRQ definieren, das der Code aus der 
While-Schleife raus kann?
2. Gibt es eine Faustformel für die Frequenz? Ich möchte zb. den Timer 
mit 50 MHz betreiben. Gibt es da irgendeine einfache Rechnung dafür, wo 
gleich Prescaler und Period rauskommen?

3. Wie kann ich an einen Port die GPIOs anders definieren. Wenn ich zum 
Beispiel den Code habe:
1
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
3
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
4
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
5
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
6
GPIO_Init(GPIOD, &GPIO_InitStruct);
Kann ich da einfach noch einen Pin draufkonfigurieren, oder überschreibt 
es die anderen Einstellungen? Also z.B. den Code nach den Code von oben:
1
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
3
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
4
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
5
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
6
GPIO_Init(GPIOD, &GPIO_InitStruct);

von Peter K. (peterka2000)


Lesenswert?

Zu 2.: Ich hab mal eine Tabelle für die Frequenzen und Prescaler 
gemacht, ist die so OK?
+----------+-----------+--------+
| Frequenz | Prescaler | Period |
+----------+-----------+--------+
| 50 MHz   | 10        | 420    |
| 40 MHz   | 10        | 336    |
| 30 MHz   | 10        | 252    |
| 20 MHz   | 10        | 168    |
| 10 MHz   | 10        | 84     |
| 7 MHz    | 12        | 49     |
| 5 MHz    | 10        | 42     |
| 3 MHz    | 7         | 36     |
| 1 MHz    | 7         | 12     |
| 750 kHz  | ?         | ?      |
| 500 kHz  | ?         | ?      |
| 250 kHz  | ?         | ?      |
| 100 kHz  | ?         | ?      |
+----------+-----------+--------+
Welche Werter kommen bei den kHz rein? Würde bei 750 kHz als Prescaler 1 
und als Period 63 OK sein?

von Ben W. (ben_w)


Angehängte Dateien:

Lesenswert?

3. du musst den Pin auch als Alternate Function setzen:
1
 // GPIO
2
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
3
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
4
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //<<< wichtig!
5
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
6
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
7
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
8
  GPIO_Init(GPIOB, &GPIO_InitStructure);
9
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3); //<<< wichtig!

2.
von welchem basis takt gehst du denn aus?

im anhang ist eine hilfestellung
ist vermutlich nicht ganz was du suchst aber es verschaft dir einen sehr 
guten überblick über die verschiedenen Taktquellen des STM32F4
Wenn du den Basistakt dann weist lässt sich ja dann mithilfe des 
Prescalers des jeweiligen Timers und der perioden variable ganz einfach 
der takt festlegen, so viel mathe traue ich dir zu :)

1. wenn du die STM standardlib benutzt musst du erstmal den interrupt 
vector konfigurieren
1
NVIC_InitTypeDef NVIC_InitStructure;
2
/* Enable the TIM1 global Interrupt */
3
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
4
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
5
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
6
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
7
  NVIC_Init(&NVIC_InitStructure);

anschließend schalltest du den Interraupt mit folgendem code an:
1
/* Enable the CC2 Interrupt Request */
2
  TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);

wenn der Interrupt eingeschaltet ist springt er die folgende Methode an:
1
void TIM1_CC_IRQHandler(void)
2
{ 
3
    /* Clear TIM1 Capture compare interrupt pending bit */
4
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
5
}

die genaue bezeichnung der IRQ Handler Methoden findest du in der 
startup_stm32f4xx.c Datei

von Peter K. (peterka2000)


Lesenswert?

3. Hängt nicht von Timern ab, ich will nur Wissen wie ich an GPIOD noch 
einen Eingang definieren kann
2. 84 MHz, so viel Mathe kann ich auch, aber wenn es eine Formel gibt, 
wär das einfacher
1. Ist bereits gelöst

von holger (Gast)


Lesenswert?

>2. 84 MHz, so viel Mathe kann ich auch, aber wenn es eine Formel gibt,
>wär das einfacher

Du kannst aus 84MHz Basistakt keine 50MHz erzeugen.
Der Prescaler ist logischwerweise nur ganzzahlig.

:2 -> 42MHz
:3 -> 28MHz
:4 -> 21MHz
...
...

von Juergen G. (jup)


Lesenswert?

Zu 3.
das geht so, wie Du das im Eingangspost geschrieben hast.

Zu 2.
Die Timer config haengt von der Clock config ab.
Dazu kommen die unterschiedlichen Peripherie Clocks.
Danach die Prescaler, danach die Register.

Du kannst Dir also die Formel ganz einfach selbst zusammenbauen.

Weil das recht komplex sein kann bietet ST die o.g. Excel Tabelle an.
Da kannst Du Dir die Formeln rausholen wenn Du willst.

von Uwe B. (derexponent)


Lesenswert?

Peter K. schrieb:
> Zu 2.: Ich hab mal eine Tabelle für die Frequenzen und Prescaler
> gemacht, ist die so OK?

die Tabelle kann nicht stimmen,
wenn du eine kleinere Frq willst, müssen die Werte
vom Vorteiler (bzw. der Periode) größer werden
(bei dir werden bei kleineren Frq die Werte auch kleiner !!)

die Formel dazu sieht so aus :

F_OUT = TIM_CLK / (TIM_Prescaler+1) / (TIM_Period+1)

z.B.
TIM_CLK = 84 MHz (hast du ja angegeben)
TIM_Prescaler=83;
TIM_Period=99;

F_OUT = 10 kHz

Gruss Uwe

von Ben W. (ben_w)


Lesenswert?

Peter K. schrieb:
> 3. Hängt nicht von Timern ab, ich will nur Wissen wie ich an GPIOD noch
> einen Eingang definieren kann

ahh sorry, wer lesen kann ist klar im vorteil :)

von Peter K. (peterka2000)


Lesenswert?

Gehen die 50 MHz dann irgendwie? Weil wie oben schon genannt wurde gilt 
ja
F_OUT = TIM_CLK / (TIM_Prescaler + 1) / (TIM_Period + 1)
Also für mich:
50 MHz = 84 MHz / (TIM_Prescaler + 1) / (TIM_Period + 1)
Aber bei 84/x = 50 müsste ja gelten x=1,68 - und das geht ja nicht, 
oder?

EDIT: Aber wie wäre es mit 84 MHz / 83 + 1) / (49 + 1) = 50 MHz ,das 
geht?
EDIT: Mist, schon wieder verrechnet

von holger (Gast)


Lesenswert?

>Gehen die 50 MHz dann irgendwie?

Nein. Es sei denn du setzt den uC Takt runter auf 100MHz.
Dann kannst du mit Prescaler = 1 den Timer mit 50MHz
laufen lassen.

>EDIT: Aber wie wäre es mit 50 MHz = 84 MHz / 84 + 1) / (50 + 1)

Was rechnest du dir da für einen Mist aus?

von Peter K. (peterka2000)


Lesenswert?

holger schrieb:
>>EDIT: Aber wie wäre es mit 50 MHz = 84 MHz / 84 + 1) / (50 + 1)
>
> Was rechnest du dir da für einen Mist aus?

Peter K. schrieb:
> EDIT: Mist, schon wieder verrechnet

von holger (Gast)


Lesenswert?

>>>EDIT: Aber wie wäre es mit 50 MHz = 84 MHz / 84 + 1) / (50 + 1)
>>
>> Was rechnest du dir da für einen Mist aus?

> EDIT: Mist, schon wieder verrechnet

So, jetzt pass mal auf:

Erst wird der Takt für den Timer durch den Prescaler geteilt.

84MHz / 84 = 1MHz

Das ist der Takt mit dem der Timer jetzt läuft.
Wie willst du von da aus wieder auf 50MHz kommen?
Du kannst diese 1MHz nicht wieder bis auf 50MHz multiplizeren.

Und wenn du jetzt diese 1MHz nimmst und durch 50 teilst
kommen da 20kHz raus. Wie zum Teufel kommst DU auf 50MHz?

von Peter K. (peterka2000)


Lesenswert?

Ich hab erst 84/50 gerechnet und dann 84 durch das Ergebnis geteilt.

von Uwe B. (derexponent)


Lesenswert?

Falls das ganze immer noch unklar ist :

Hier mal eine kleine Tabelle welche Frequenzen mit 84MHz
Eingangstakt möglich sind :
1
Teiler | F_OUT
2
---------------
3
   1   |  84 MHz
4
   2   |  42 MHz
5
   3   |  28 MHz
6
   4   |  21 MHz
7
   5   |  16,8 MHz
8
   6   |  14 MHz
9
10
usw

wobei der Wert vom Teiler dann auf die Variabeln
"TIM_Prescaler" und "TIM_Periode" aufgeteilt werden müssen

so schwer ist das nicht und wie du siehst
ist der Wert "50 MHz" nicht dabei

die einzigste Möglichkeit ist die "holger" schon beschrieben hat :
die PLL so ändern das der Systemtakt bei 100 MHz liegt
um damit einen TIM_CLK von 50 MHz zu erreichen


Gruss Uwe

von Uwe (Gast)


Lesenswert?

Tja, wenn doch jeder Timer ne eigene PLL hätte ...

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.