Stm32F4 Timer

Gast #4879917
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
}
Gast #4879926
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
Gast #4879935
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
}
Gast #4879948
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
Gast #4879957
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 ;)
Gast #4879968
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.
Gast #4879980
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.
Gast #4879992
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
Gast #4879998
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
Gast #4880005
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.
Gast #4880066
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.
Gast #4880089
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.
Gast #4880121
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
Gast #4880144
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);
Gast #4880162
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;
Gast #4880171
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?
Gast #4880181
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.
Gast #4880638
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.
Gast #4880641
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

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