Forum: Mikrocontroller und Digitale Elektronik STM32F2/4 Rotary Encoder: Wie "nur ein Interrupt pro Schritt"?


von Random .. (thorstendb) Benutzerseite


Lesenswert?

Moin,

jemand Erfahrung mit dem TIMER Rotary Encoder der STM32F2/F4? Mich 
wundert, dass
- der Counter immer 2 oder 4 weiterzählt, je nach SMS=1,2 oder 3
- viel zu viele IRQs generiert werden, mind. 1 pro Counter, aber auch 
"zufällig" sehr viel mehr als der Stand vom CNT Register

Habe das ganze mit der HAL gelöst, in der Hoffnung, es portierbar zu 
halten. Die structs werden im Konstruktor auf null gesetzt.
Sinnhaftigkeit von C++ auf µC? Ganz einfach: Ist mein Testprojekt, um 
genau das herauszufinden :-)
1
bool CRotary::Rotary_Initialize()
2
{
3
  __TIM3_CLK_ENABLE();
4
  __GPIOB_CLK_ENABLE();
5
  
6
  GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
7
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
8
  GPIO_InitStruct.Pull = GPIO_PULLUP;
9
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
10
  GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
11
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
12
13
  timer.Instance = TIM3;
14
  timer.Init.Period = 0xFFFF;
15
  timer.Init.CounterMode = TIM_COUNTERMODE_UP;
16
  timer.Init.Prescaler = 0;
17
  timer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
18
19
  encoder.EncoderMode = TIM_ENCODERMODE_TI12;
20
  encoder.IC1Filter = 0x0F;
21
  encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
22
  encoder.IC1Prescaler = TIM_ICPSC_DIV1;
23
  encoder.IC1Selection = TIM_ICSELECTION_DIRECTTI;
24
  encoder.IC2Filter = 0x0F;
25
  encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
26
  encoder.IC2Prescaler = TIM_ICPSC_DIV1;
27
  encoder.IC2Selection = TIM_ICSELECTION_DIRECTTI;
28
29
  if (HAL_TIM_Encoder_Init(&timer, &encoder) != HAL_OK)
30
    return false;
31
32
  HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);
33
  HAL_NVIC_EnableIRQ(TIM3_IRQn);
34
35
  if(HAL_TIM_Encoder_Start_IT(&timer, TIM_CHANNEL_1) != HAL_OK)
36
    return false;
37
 
38
  return true;
39
}

: Bearbeitet durch User
von N. M. (mani)


Lesenswert?

Random .. schrieb:
> der Counter immer 2 oder 4 weiterzählt, je nach SMS=1,2 oder 3

Das wäre merkwürdig. Normalerweise kenne ich das SMS Register so, dass 
es angibt auf was für Flanken es reagieren soll. Also einfach, zweifach 
oder vierfach Flankenauswertung.
Aber eine Flanke bleibt ein Count!

Random .. schrieb:
> viel zu viele IRQs generiert werden

Erste Mal, wofür brauchst du die Interrupts überhaupt? Oft tut es ein 
Polling des Count Registers z.B. alle 1 bis 100ms.

Random .. schrieb:
> mind. 1 pro Counter, aber auch "zufällig" sehr viel mehr als der Stand
> vom CNT Register

Da liegt wahrscheinlich dein Problem. Hast du dir Mal die Signale 
angesehen mit einem Oszi oder Logic Analyzer? Wahrscheinlich prellt da 
irgendwas oder was anderes stimmt mit deinen Signalen nicht.

Wie sieht der Aufbau aus?
Was für einen Encoder nimmst du?
Und wie ist er angeschlossen?

von Philip S. (phs)


Lesenswert?

Hi,

 ich hatte das mal mit dem F103 gemacht; der Timer im F4 ist an der 
Stelle aber m.W. gleich:

https://github.com/PhischDotOrg/stm32f1-blinkenbike/blob/master/RotaryEncoder.hpp

Verwendet hatte ich diesen billigen KY-040 Rotary Encoder.

Ergänzend zu den Kommentaren im Source Code: Die Entprellung wird in dem 
Setup letztlich von der Timer Hardware gemacht. Hier wird der Input 
Filter / Edge Detector ausgenutzt. In meinem Projekt wird der Rotary 
Encoder von einem Menschen bedient; dreht also nicht soo schnell. Ich 
hatte den Filter deshalb sehr "langsam" / "tiefpassig" (wie sagt man 
denn da richtig?) eingestellt. Siehe Zeile #111.

Wenn ich mich recht erinnere, dann hab' ich die Sequenz mehr oder 
weniger aus dem Datenblatt abgeschrieben.

Vielleicht hilft's ja.

von N. M. (mani)


Lesenswert?

Random .. schrieb:
> encoder.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;

Im RefManual steht was von "CC1NP and CC2NP must be kept low". Stimmt 
das dann?

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Hab diverse Kombinationen durchprobiert, klappt alles nicht.
Die sauberste Erkennung ist tatsächlich mittels CC1 und CC2 (also CNT+4 
pro Schritt). Eine Filterung der IRQ Generierung auf 1/4 hab ich nicht 
rausgefunden ...

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.