Forum: Mikrocontroller und Digitale Elektronik STM32 Input Capture mit Counter Reset


von Holger K. (holgerkraehe)


Lesenswert?

Hallo zusammen

Ich möchte mit dem STM32 die Zeit zwischen zwei Nulldurchgängen messen.

Dazu möchte ich den InputCapture nutzen.


Meine Idee:

TIMER zählt von 0 an hoch..
-> Interrupt kommt: Zähler wird zurückgesetzt und zählt wieder von 0 an 
weiter
1
void TIM3_IRQHandler(void)
2
{ 
3
  if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET) 
4
  {
5
    /* Clear TIM3 Capture compare interrupt pending bit */
6
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
7
    if(CaptureNumber == 0)
8
    {
9
      /* Get the Input Capture value */
10
      IC3ReadValue1 = TIM_GetCapture2(TIM3);
11
      CaptureNumber = 1;
12
    }
13
    else if(CaptureNumber == 1)
14
    {
15
      /* Get the Input Capture value */
16
      IC3ReadValue2 = TIM_GetCapture2(TIM3); 
17
      
18
      /* Capture computation */
19
      if (IC3ReadValue2 > IC3ReadValue1)
20
      {
21
        Capture = (IC3ReadValue2 - IC3ReadValue1); 
22
      }
23
      else
24
      {
25
        Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); 
26
      }
27
      /* Frequency computation */ 
28
      TIM3Freq = (uint32_t) SystemCoreClock / Capture;
29
      CaptureNumber = 0;
30
    }
31
  }
32
}

Es gibt diesen Code von ST

Aber so wie ich das verstehe, zählt der Zähler einfach weiter nach einem 
Interrupt.

Wie kann ich dies ändern?

von m.n. (Gast)


Lesenswert?

Holger Krähenbühl schrieb:
> Wie kann ich dies ändern?

Laß den Timer frei weiterlaufen und setze ihn nie auf 0 zurück!
Um das letzte Intervall zu erhalten, wird der alte Wert gespeichert und 
beim nächsten Capture gerechnet: neuer_wert - alter_wert

Auf die Weise können mehrere Capture-Eingänge mit einem Timer 
ausgewertet werden. Wenn die Intervalle länger werden, müssen die 
Überlaufe berücksichtigt werden.

von Holger K. (holgerkraehe)


Lesenswert?

m.n. schrieb:
> Laß den Timer frei weiterlaufen und setze ihn nie auf 0 zurück!
> Um das letzte Intervall zu erhalten, wird der alte Wert gespeichert und
> beim nächsten Capture gerechnet: neuer_wert - alter_wert
>
> Auf die Weise können mehrere Capture-Eingänge mit einem Timer
> ausgewertet werden. Wenn die Intervalle länger werden, müssen die
> Überlaufe berücksichtigt werden.

Das erscheint mir ein wenig kompliziert.

Schau dir mal dieses Dokument an:

http://www.st.com/web/en/resource/technical/document/application_note/DM00042534.pdf

Auf Seite 12 steht:

Particular case
To facilitate the input capture measurement, the timer counter is reset 
after each rising edge
detected on the timer input channel by:
• selecting TIxFPx as the input trigger by setting the TS bits in the 
SMCR register
• selecting the reset mode as the slave mode by configuring the SMS bits 
in the SMCR
register


Ich benötige nur einen inputCapture...
Leider weiss ich nicht wie man TIxFPx als input wählt und die 
entsprechenden TS bits im SMCR setzt...

Weiss jemand mehr darüber?
Geht das einfach mit TIM_SetCounter(TIM3,0); im Interrupt?


Was ich jedoch noch brauche ist 32 Bit Auflösung.
Somit muss ich wohl TIM3 mit TIM2 verbinden.

Leider habe ich ausser einer AN2592 keinen Code gefunden.
Dort wird beschrieben wie das geht, aber nicht wie man es programmiert.

von m.n. (Gast)


Lesenswert?

Holger Krähenbühl schrieb:
> Was ich jedoch noch brauche ist 32 Bit Auflösung.
> Somit muss ich wohl TIM3 mit TIM2 verbinden.

Das geht mit einem 16 Bit Timer, sofern man die Überläufe 
berücksichtigt.
Willst Du eine Frequenz messen? Dafür habe ich ein Beispiel.
http://www.mino-elektronik.de/FM_407/fmeter_407.htm#a5

Holger Krähenbühl schrieb:
> Das erscheint mir ein wenig kompliziert.

Man muß es einmal verstehen und wird es dann immer wieder so machen ;-)

von Holger K. (holgerkraehe)


Lesenswert?

m.n. schrieb:
> Das geht mit einem 16 Bit Timer, sofern man die Überläufe
> berücksichtigt.
> Willst Du eine Frequenz messen? Dafür habe ich ein Beispiel.

Danke!

Ja ich möchte einen 50Hz Sinus messen.
Er kann im Bereich von 40-65 Hz liegen.

Möchte die Frequenz möglichst genau messen.
Also mind. auf 10mHz

50.0xHz


In dieser Application Note auf Seite 12 steht, mann soll den Counter 
resetten.

http://www.st.com/web/en/resource/technical/document/application_note/DM00042534.pdf

Damit kann man dan direkt das Capture Register als Periodendauer 
verwenden.
Doch wie resette ich den Counter?


Wenn ich dein Programm richtig verstehe, dann zählst du bei einem 
Überlauf von TIM8 manuell (mit CPU) den Überlauf hoch.

Dies sollte doch aber auch durch chaining machbar sein.

Steht in Applicationnote: AN2592

von m.n. (Gast)


Lesenswert?

Ich möchte jetzt nicht den ganzen ST-Kram durchlesen.
Im Referenzhandbuch des STM32F4xx (Du verwendest wohl einen F1xx) ist 
ein "PWM input mode" beschrieben, der mit einem Reset des Timers 
arbeitet. Vielleicht kuckst Du Dir dort die Initialisierung ab.

Mir ist diese Vorgehensweise zu 'steif'.

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.