Forum: Mikrocontroller und Digitale Elektronik Stm32F4 Timer


von stm32 einsteiger (Gast)


Lesenswert?

Hallo,

Ich habe ein STM32F429 mit 168MHz Takt.

Nun wollte ich den Timer5 im 10 Sekundentakt einen Interrupt auslösen, 
Nur leider Läuft der Timer zu schnell.
1
void Tim5_Configuration(void)
2
{
3
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
4
5
6
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
7
  // Time Base initialisieren
8
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
9
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
10
  
11
  //10 sekunden
12
  TIM_TimeBaseInitStructure.TIM_Prescaler = 100000-1;
13
  TIM_TimeBaseInitStructure.TIM_Period = 8400 - 1;  
14
  
15
16
17
  
18
  TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
19
  TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);
20
21
  // Interrupt enable für Update
22
  TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
23
24
  // um den Timer loslaufen zu lassen
25
  TIM_Cmd(TIM5,ENABLE);
26
}

von 6a66 (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> Hallo,
>
> Ich habe ein STM32F429 mit 168MHz Takt.
>
> Nun wollte ich den Timer5 im 10 Sekundentakt einen Interrupt auslösen,
> Nur leider Läuft der Timer zu schnell.
> void Tim5_Configuration(void)
> {
>   TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
>
>   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
>   // Time Base initialisieren
>   TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
>   TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
>
>   //10 sekunden
>   TIM_TimeBaseInitStructure.TIM_Prescaler = 100000-1;
>   TIM_TimeBaseInitStructure.TIM_Period = 8400 - 1;
>
>
>
>   TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
>   TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);
>
>   // Interrupt enable für Update
>   TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
>
>   // um den Timer loslaufen zu lassen
>   TIM_Cmd(TIM5,ENABLE);
> }

Nach meinen Berechnungen müsste der APB/AHB Vorteile auf 2 stehen so 
dass Dein Timer mit 84MHz läuft. Korrekt?
Dann müssten rein rechnereisch 0,1Hz rauskommen.
Aber: Wie breit ist der Vorteiler vom STM32-Timer? 16bit?
Passen da Dez100000 rein?
Wenn nicht käme dam 100000-64k rein = 34464
Der Timer würde dann mit 0,292Hz laufen = alle 3,4s
Korrekt?

Jetzt weißt Du was Du ändern musst.

rgds

von stm32 einsteiger (Gast)


Lesenswert?

Der Timer läuft jetzt aber immernoch zu schnell ca alle 5Sekunden wird 
ein Interrupt ausgelöst.

Ist das überhaupt richtig?
 TIM_TimeBaseInitStructure.TIM_Period = 8400 - 1;

84000000:100000 = 840

1
void Tim5_Configuration(void)
2
{
3
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
4
5
6
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
7
  // Time Base initialisieren
8
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV2; //84MHz
9
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
10
  
11
  //10 sekunden
12
  TIM_TimeBaseInitStructure.TIM_Prescaler = 100000-1;
13
  TIM_TimeBaseInitStructure.TIM_Period = 8400 - 1;  
14
  
15
16
17
  
18
  TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
19
  TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);
20
21
  // Interrupt enable für Update
22
  TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
23
24
  // um den Timer loslaufen zu lassen
25
  TIM_Cmd(TIM5,ENABLE);
26
}

von ui (Gast)


Lesenswert?

rechne doch einfach selber. 6a66 hat dir den rechenweg doch schon 
gesagt.

von stm32 einsteiger (Gast)


Lesenswert?

6a66 schrieb:

> Nach meinen Berechnungen müsste der APB/AHB Vorteile auf 2 stehen so
> dass Dein Timer mit 84MHz läuft. Korrekt?
> Dann müssten rein rechnereisch 0,1Hz rauskommen.
> Aber: Wie breit ist der Vorteiler vom STM32-Timer? 16bit?
> Passen da Dez100000 rein?
> Wenn nicht käme dam 100000-64k rein = 34464
> Der Timer würde dann mit 0,292Hz laufen = alle 3,4s
> Korrekt?
>
> Jetzt weißt Du was Du ändern musst.
>
> rgds

Hab ich:
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV2; //84MHz

Das wäre wie von ihnen 3,4s
100000-64k rein = 34464

Wenn ich für 10Sekunden rechne
100000-10k rein = 90000

Das geht aber nicht weil das Register ja nur 16Bit hat

von ui (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV2; //84MHz

ich stell dir mal ne Frage. Wenn es TIM_CKD_DIV2 gibt, könntest du dir 
dann auch vorstellen, dass es einen Vorteiler mit Faktor 4 gibt?
Wenn du eclipse nutzt, klick doch einfach mal auf STRG+TIM_CKD_DIV2, 
dann kommst du zur definition. Vielleicht gibts da noch mehr davon ;)

von stm32 einsteiger (Gast)


Lesenswert?

Hab ich:
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4; //42MHz

100000 passen ja nicht in den vorteiler.

mein Problem ist wie ich das berechne das ich auf 10Sekunden komme 
komme, das hatte ich gefragt.

von ui (Gast)


Lesenswert?

es gibt in der stm stdlib auch gute beispiele. Ist im Ordner examples.
Noch ein Tipp: Es gibt auch eine Periode, die du einstellen kannt. Da 
passt auch ein sehr großer Wert rein.

von stm32 einsteiger (Gast)


Lesenswert?

ich hab das jetzt so

  //10 sekunden
  TIM_TimeBaseInitStructure.TIM_Prescaler = 42000;  //1MHZ
  TIM_TimeBaseInitStructure.TIM_Period = 22000  - 1;


42000000 : 42000 = 1MHz Timertakt

bis 22000 soll er zählen ca.10Sekunden

ist das so Richtig.

von hp-freund (Gast)


Lesenswert?

42000000 : 42000 = 1000 nicht 1000000

von ui (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> 42000000 : 42000 = 1MHz Timertakt
>
> bis 22000 soll er zählen ca.10Sekunden
>
> ist das so Richtig.

hp-freund schrieb:
> 42000000 : 42000 = 1000 nicht 1000000

selber denken. Wenn du 1kHz "Takt" hast, bis wie viel musst du dann 
zählen um auf 10 Sekunden zu kommen?

von 6a66 (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> //10 sekunden
>   TIM_TimeBaseInitStructure.TIM_Prescaler = 100000-1;
>   TIM_TimeBaseInitStructure.TIM_Period = 8400 - 1;

Was hälst Du davon:

Prescaler 10000 und Period 84000?
Oder Prescaler 8400 und Period 100000?
oder ....

Facepalm :)

rgds

von 6a66 (Gast)


Lesenswert?

6a66 schrieb:
> Aber: Wie breit ist der Vorteiler vom STM32-Timer? 16bit?
> Passen da Dez100000 rein?
> Wenn nicht käme dam 100000-64k rein = 34464

Lösen wir mal auf:
Was passiert wenn ich 100000 in ein 16-bit register schreibe?
100000 = hex 186a0.
Die "1" vorneweg wird abgeschnitten da das ja das 17. bit ist.
Also schreibt der Prozessor in das Register 86a0 = 34464.
Deswegen ist der Takt eben kürzer.

rgds

von hp-freund (Gast)


Lesenswert?

Wegen solchen und ähnlichen "Kleinigkeiten":

STM32CubeMX

von stm32 einsteiger (Gast)


Lesenswert?

TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4; //42MHz

  //10 sekunde
  TIM_TimeBaseInitStructure.TIM_Prescaler = 42000; //1000Hz
  TIM_TimeBaseInitStructure.TIM_Period = 10000  - 1;


Trotzdem läuft der timer nur ca 5 Sekunden

von hp-freund (Gast)


Angehängte Dateien:

Lesenswert?

Siehe Bild.

von Bernd (Gast)


Lesenswert?

Um mir die Clockeinstellungen zu veranschaulichen benutze ich die 
Software  STM32CubeMX von ST. Man muss dann zwar wissen bzw. prüfen wie 
seine Einstellungen sind, aber dann kann man sehr anschaulich 
verschiedene Einstellungen durchspielen. Ich lege mir zu jedem Projekt 
immer auch ein CubeMX Projekt mit den konkreten Einstellungen an. Dann 
habe ich bei Bedarf schnell einen Überblick.

von stm32 einsteiger (Gast)


Lesenswert?

STM32CubeMX von ST hab ich nicht.

TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4; //42MHz

//10 sekunde
TIM_TimeBaseInitStructure.TIM_Prescaler = 4200;
TIM_TimeBaseInitStructure.TIM_Period = 100000  - 1;


nach ca 5 Sekunden kommt schon der Interrupt.

köönte mir denn jemand den Rechenweg aufzeigen ich komme damit ncht auf 
die 10 Sekunden.

Timertakt = 42000000 : 4200 = 10000

bis 10000 soll er zählen aber nach 5-6 Sekunden wird der Interrupt 
ausgelöst.

von hp-freund (Gast)


Lesenswert?

Sieh dir das Bild an.
Besonders unten rechts!

von stm32 einsteiger (Gast)


Lesenswert?

Den Timer hab ich doch auf 42MHz TIM_CKD_DIV4 eingestellt so ist doch 
auch auf dem Bild

von hp-freund (Gast)


Lesenswert?

Muss ich das Bild wirklich erklären?

von stm32 einsteiger (Gast)


Lesenswert?

sorry
so lange arbeite ich noch nicht mit dem stm32
der stm läuft mit 168mHz

Den Timer hab ich mit TIM_CKD_DIV4 auf 42MHz eingestellt.

oder bin ich da verkehrt in der annnahme.

Wäre das denn möglich zu erklären wie die korrekte Einstellung ist, 
damit ich das auch nachvollziehen kann.

von Bernd (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> STM32CubeMX von ST hab ich nicht.

http://www.st.com/en/development-tools/stm32cubemx.html

Ist kostenlos.

von stm32 einsteiger (Gast)


Lesenswert?

Bernd schrieb:
> http://www.st.com/en/development-tools/stm32cubemx.html
>
> Ist kostenlos.

ich möchte mich dort aber nicht anmelden.

von hp-freund (Gast)


Lesenswert?

Deine Phantasie lässt in jeder Richtung zu wünschen übrig ;-)

von Bernd (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> Bernd schrieb:
>> http://www.st.com/en/development-tools/stm32cubemx.html
>>
>> Ist kostenlos.
>
> ich möchte mich dort aber nicht anmelden.

Dann lass es oder nimm eine Wegwerf Mailadresse. War auch nur als Tipp 
gedacht. Macht die Sache übersichtlicher. Aber wer nicht will... gut.

von stm32 einsteiger (Gast)


Lesenswert?

Bernd schrieb:
> stm32 einsteiger schrieb:
>> Bernd schrieb:
>>> http://www.st.com/en/development-tools/stm32cubemx.html
>>>
>>> Ist kostenlos.
>>
>> ich möchte mich dort aber nicht anmelden.
>
> Dann lass es oder nimm eine Wegwerf Mailadresse. War auch nur als Tipp
> gedacht. Macht die Sache übersichtlicher. Aber wer nicht will... gut.

Das hab ich schon verstanden wie sie es gemeint haben.

Aber scheinbar kann mir niemand erklären wie ich die Timerconfig 
berechen damit ich auf meine 10Sekunden komme

von hp-freund (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> Aber scheinbar kann mir niemand erklären ....

Scheint so.

von stm32 einsteiger (Gast)


Lesenswert?

hp-freund schrieb:
> stm32 einsteiger schrieb:
>> Aber scheinbar kann mir niemand erklären ....
>
> Scheint so.

Scheinbar ist es auch nicht möglich vernünftige Stze zu schreiben !


ich habs jetz so läufts genau 10Sekunden
1
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
2
3
  // Der Timer wird mit 84MHz getaktet (APB1 Domain mit 42MHz X2 siehe Seite 85 im Ref.Man.)
4
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
5
  // Time Base initialisieren
6
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4; 
7
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
8
9
  //10 sekunde
10
  TIM_TimeBaseInitStructure.TIM_Prescaler = 4200; //1000Hz
11
  TIM_TimeBaseInitStructure.TIM_Period = 200000  - 1;
12
  
13
  
14
  TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
15
  TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);
16
17
  // Interrupt enable für Update
18
  TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
19
20
  // um den Timer loslaufen zu lassen
21
  TIM_Cmd(TIM5,ENABLE);

von Jürgen H. (nobody)


Lesenswert?

Wenn dir die Erklärungen nicht reichen, ist ja nicht so das oben nichts 
stehen würde, dann nimm das Datenblatt.

Es haben ja schon viele geschafft auch aus diesem schlau zu werden. ;-)

von stm32 einsteiger (Gast)


Lesenswert?

Jürgen H. schrieb:
> Wenn dir die Erklärungen nicht reichen, ist ja nicht so das oben
> nichts
> stehen würde, dann nimm das Datenblatt.
>
> Es haben ja schon viele geschafft auch aus diesem schlau zu werden. ;-)

Aber meine Frage bleibt weiterhin bestehen wie ich auf diese werte 
komme,
diese zuberechen habe ich ein paar Probleme

  TIM_TimeBaseInitStructure.TIM_Prescaler = 4200; //1000Hz
  TIM_TimeBaseInitStructure.TIM_Period = 200000  - 1;

von hp-freund (Gast)


Lesenswert?

Das Problem liegt wohl darin das dir das Verständnis fehlt, obwohl Du 
selbst geschrieben hast:

// Der Timer wird mit 84MHz getaktet (APB1 Domain mit 42MHz X2 siehe 
Seite 85 im Ref.Man.)

Das ist auch genau das was ich mehrfach durch lenken deiner Augen auf 
das Bild sagen wollte.
Es ist eben nicht so das der Timer mit 42MHz getaktet wird, sondern mit 
84MHz.

Ein weiterer Fehler ist:

TIM_TimeBaseInitStructure.TIM_Prescaler = 4200; //1000Hz

Das sind eben nicht 1000Hz. Sondern das:

TIM_TimeBaseInitStructure.TIM_Prescaler = 84000;

Alles klar?

von hp-freund (Gast)


Lesenswert?

Ja, ich weiß, ist gemein :)

Im Ernst, der Prescaler hat nur 16 bit.
Also gibt es so keine 1000Hz.

von Axel R. (Gast)


Lesenswert?

Unglaublich
Der Timer wird von APB1 getaktet! da steht im Bild oben "x2". Ich will 
garnicht wissen, was das wohl bedeutet...
Da kann man sicher auch drann schrauben.

Wir haben früher, mussten manchmal sogar, im Mathe eine GEGENPROBE 
machen müssen, wenn wir was ausgerechnet hatten ( 5.Klasse ).
Genauso macht man das hier auch.

StromTuner

Ich verfolge das Forum seit mittlerweile gut 10-12 Jahren.
Es ist erschreckend, wie/wohin sich die Probleme verlagern.
Es wundert mich nicht, das sich viele User mittlerweile zurückziehen.

von W.S. (Gast)


Lesenswert?

stm32 einsteiger schrieb:
> TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
>   TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

Wenn du weiterhin dich derart konsequent von jeglichem Verstehenwollen 
der Hardware fernhältst, dann wird das nichts bis in alle Ewigkeit.

Ich will jetzt mal nicht danach fragen, warum du für ein Signal "im 10 
Sekundentakt" unbedingt einen der Hardware-Timer gebrauchen willst. 
Sowas macht man sinnvollerweise über die (hoffentlich vorhandene) 
Software-Systemuhr, die vom SysTick angetrieben wird, weil das ganze 
derart langsam ist, daß jedem Timer dabei die Füße schier einschlafen 
würden. Jedenfalls bei einem Peripherietakt von rund 80 MHz. Dein 
effektives Teilerverhältnis müßte so bei 800 Millionen liegen. Das sind 
rund 30 Bit. Also denke mal darüber nach.

Aber wenn du sowas nun schon mal partout tun willst, dann lies das 
Referenzmanual und sieh dort nach, was du dort bei diesem Timer 
überhaupt einstellen kannst - anstatt irgendwelche finsteren ST-Lib 
Prozeduren zu zelebrieren.

Grrmpf...

W.S.

von stm32 einsteiger (Gast)


Lesenswert?

hp-freund schrieb:
> Das Problem liegt wohl darin das dir das Verständnis fehlt, obwohl
> Du selbst geschrieben hast:
>
> // Der Timer wird mit 84MHz getaktet (APB1 Domain mit 42MHz X2 siehe
> Seite 85 im Ref.Man.)
>
> Das ist auch genau das was ich mehrfach durch lenken deiner Augen auf
> das Bild sagen wollte.
> Es ist eben nicht so das der Timer mit 42MHz getaktet wird, sondern mit
> 84MHz.
>
> Ein weiterer Fehler ist:
>
> TIM_TimeBaseInitStructure.TIM_Prescaler = 4200; //1000Hz
>
> Das sind eben nicht 1000Hz. Sondern das:
>
> TIM_TimeBaseInitStructure.TIM_Prescaler = 84000;
>
> Alles klar?

Ja jetzt ist mir das klar

ich bin davon ausgegangen das. durch 4 ich dann den Timerclock
auf 42Mhz habe das war falsch.
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV4


Aber wozu ist diese Einstellung daran hapere ich noch .

könnte mir das jemand kurz erklãren.
danke

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.