Forum: Mikrocontroller und Digitale Elektronik STM32F103 Timer Input Capture: "TIM_ICPolarity_BothEdge" nicht verfügbar - Workaround?


von Info (Gast)


Lesenswert?

Mit der Capture-Einstellung "TIM_ICPolarity_BothEdge" an Timer 4 Channel 
2 (PB7) werden nur steigende Flanken erkannt, weil offenbar keiner der 
Timer diese Möglichkeit hat:

stm32f10x_tim.c
1
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
2
{
3
  ... 
4
  if((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) ||
5
     (TIMx == TIM4) ||(TIMx == TIM5))
6
  {
7
    assert_param(IS_TIM_IC_POLARITY(TIM_ICInitStruct->TIM_ICPolarity));
8
  }
9
  else
10
  {
11
    assert_param(IS_TIM_IC_POLARITY_LITE(TIM_ICInitStruct->TIM_ICPolarity));
12
  }
13
14
  ...

stm32f10x_tim.h
1
...
2
#define  TIM_ICPolarity_Rising             ((uint16_t)0x0000)
3
#define  TIM_ICPolarity_Falling            ((uint16_t)0x0002)
4
#define  TIM_ICPolarity_BothEdge           ((uint16_t)0x000A)
5
#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
6
                                      ((POLARITY) == TIM_ICPolarity_Falling))
7
#define IS_TIM_IC_POLARITY_LITE(POLARITY) (((POLARITY) == TIM_ICPolarity_Rising) || \
8
                                           ((POLARITY) == TIM_ICPolarity_Falling)|| \
9
                                           ((POLARITY) == TIM_ICPolarity_BothEdge))
10
...

Erstens: wo landet die Warnung der Library, dass dieser Trigger gar 
nicht vorhanden ist?

Und: gibt es eine Möglichkeit, trotzdem auf beide Flanken zu reagieren 
(jedes Mal umschalten - wie erkennt man die erste Flanke?)?

von Ulrich H. (lurchi)


Lesenswert?

Die Polarität der Flanke die als nächstes kommt, erkennt man z.B. am 
Zustand des Port. Wenn da also eine Low anliegt kann es nur noch 
aufwärts gehen.

Die Alternative wäre es 2 Capture Kanäle zu nutzen, einer für steigende 
und einer für fallende Flanke. Ggf. muss man dann halt 2 Pins nutzen.

von Info (Gast)


Lesenswert?

Man kann einen zweiten Channel am selben Pin benutzen:
1
    TIM_ICStructInit( &TIM_IC_InitStructure );
2
    TIM_IC_InitStructure.TIM_Channel =                      TIM_Channel_1;
3
    TIM_IC_InitStructure.TIM_ICPolarity =                   TIM_ICPolarity_Rising;
4
    TIM_IC_InitStructure.TIM_ICSelection =                  TIM_ICSelection_IndirectTI;
5
    TIM_IC_InitStructure.TIM_ICPrescaler =                  TIM_ICPSC_DIV1;
6
    TIM_IC_InitStructure.TIM_ICFilter =                     0x00;
7
    TIM_ICInit(TIM4, &TIM_IC_InitStructure);
8
    
9
    TIM_ICStructInit( &TIM_IC_InitStructure );
10
    TIM_IC_InitStructure.TIM_Channel =                      TIM_Channel_2;
11
    TIM_IC_InitStructure.TIM_ICPolarity =                   TIM_ICPolarity_Falling;       // !
12
    TIM_IC_InitStructure.TIM_ICSelection =                  TIM_ICSelection_DirectTI;    // !
13
    TIM_IC_InitStructure.TIM_ICPrescaler =                  TIM_ICPSC_DIV1;
14
    TIM_IC_InitStructure.TIM_ICFilter =                     0x00;
15
    TIM_ICInit(TIM4, &TIM_IC_InitStructure);

Aktivierung in NVIC nicht vergessen.

von Philipp (Gast)


Lesenswert?

Bin gerade zufällig auf den Beitrag gestoßen. Habe im Moment selbst das 
Problem, dass ich gerne auf beide Flanke ein InputCapture Event auslösen 
möchte.

Finde die im vorherigen Beitrag vorgeschlagene Idee super.
Habe gleich mal versucht, das im Keil Simulator zu simulieren. Leider 
wird dort nach wie vor nur bei der steigenden Flanke ein Interrupt 
ausgelöst.

Kann mir jemand bestätigen, dass diese Methode auf der realen Hardware 
funktioniert?

Beitrag #5078068 wurde vom Autor gelöscht.
von Mitlesa (Gast)


Lesenswert?

Philipp schrieb:
> Kann mir jemand bestätigen, dass diese Methode auf der realen Hardware
> funktioniert?

Kannst du selbst (in der Praxis) herausfinden indem du einen
zweiten Pin mit dem Interrupt-Pin verbindest, ihn vom Programm
aus gezielt low und high setzt und daraus analysierst ob ein
Interrupt aufgetreten ist. Ist auch mit dem Debugger leicht
nachzuvollziehen. Da braucht es kein Oszilloskop dazu.

von Philipp (Gast)


Lesenswert?

Klasse Idee!

Habe das gerade mal am F103 getestet. Einfach ein Signal mit ~60000 
Taktzyklen High und ~30000 Taktzyklen low erzeugt und das mit einem 
Draht auf einen Timer Pin gefüttert. Den Timer nach jedem Interrupt dann 
wieder auf 0 gesetzt.

Beim Debuggen hat man deutlich gesehen, dass in CCR1 ca. der doppelte 
Wert wie in CCR2 gemessen wird. Es reagieren also beide Channels auf je 
eine Flankenart auf dem gleichen Pin.

Bestätigt also, dass das ganze so funktioniert, wie der TO es in seinem 
Beitrag beschrieben hat.

Vielen Dank!

von Philipp (Gast)


Lesenswert?

Nachtrag:

Im Simulator vom Keil µVision 5.24 funktioniert der zweite Capture 
Channel mit dem selben Programmcode nicht. Nur ein Channel "captured"!

von Mitlesa (Gast)


Lesenswert?

Philipp schrieb:
> Einfach ein Signal mit ~60000
> Taktzyklen High und ~30000 Taktzyklen low erzeugt

... äääääähhhhmmmmm ... ich stelle mir das schwierig vor ....

Ein digitales Taktsignal hat immer gleich viele Low- und
High-Phasen ..... allerhöchstens +-1 wenn man die Unendlich-
keit abschneidet, also einen Ausschnitt betrachtet.

Das trifft dann auch auf die Taktflanken zu ....

von Philipp (Gast)


Lesenswert?

Aber hier geht es ja nicht um die ANZAHL der Taktflanken, sondern um die 
ZEIT zwischen positiver- und negativer Flanke. Mit der unterschiedlichen 
High- und Low Zeit konnte ich feststellen ob die Channels auch jeweils 
bei unterschiedlichen Flanken triggern.

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.