cancel
Showing results for 
Search instead for 
Did you mean: 

How to get interrupt on counter overflow with Quadrature Encoder with Cube and HAL?

Stefan Wozniak
Associate III
Posted on March 26, 2017 at 14:09

Hi,

I want to use Timer with Quadrature Encoder. I'm new on STM32 so I'm trying to start with Cube and HAL.

I'm able to setup STM32F411 to count pulses but there is an only 16bit counter. I need to measure pulses up to 400k.

Can I rise interrupt on counter overflow to store revolutions? I want to do this using Cube and HAL. I was trying a lot of settings and interrupts but I'm unable to get interrupt from an encoder.

Can you help me?

Thanks in advance.

Steve

#cube #cube-mx #quadrature-encoder #stm32-cube #stm32f411 #quadrature
21 REPLIES 21
Posted on September 13, 2017 at 09:55

Until someone actually takes two PWM timers and simulates a quadrature encoder pulse train and does the experiments to find the limitations of ST's hardware quadrature encoding, then that is just speculation.For all we know, tiny pulse widths caused by sharp reversals could be lost with both overflow interrupt AND periodic sampling ESPECIALLY if the input capture glitch filter bits are enabled.

What I do know is that my code is working fine for my application. Granted, I have much more excess precision from my encoders than is required, such that I would never notice a lost count out of a million (and your unproven scenario would be quite rare - You would have to have a sharp reversal exactly at the 32768 count increment or decrement).

Posted on September 22, 2017 at 19:36

Look Jan! See how much cleaner the code is with library functions with no loss in performance:

Before:

void TIM4_IRQHandler()
{
 if (~TIM4->SR & TIM_SR_UIF)
 return;
 
 if ((TIM4->CNT == 65535) && (TIM4->CR1 & TIM_CR1_DIR))
 {
 Encoder_Position_Offset += 32769;
 TIM4->CNT = 32768;
 }
 else if ((TIM4->CNT == 0) && (~TIM4->CR1 & TIM_CR1_DIR))
 {
 Encoder_Position_Offset -= 32768;
 TIM4->CNT = 32768;
 }
 TIM4->SR = ~TIM_SR_UIF;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

After:

static inline void Encoder_Overflow_IRQ_Handler(TIM_TypeDef* Encoder)
{
 if (!LL_TIM_IsActiveFlag_UPDATE(Encoder))
 return;
 uint32_t direction = LL_TIM_GetDirection(Encoder);
 uint32_t count = LL_TIM_GetCounter(Encoder);
 if ((count == 0) && (direction == LL_TIM_COUNTERDIRECTION_UP))
 {
 Encoder_Position_Offset[Motor] -= 32768;
 LL_TIM_SetCounter(Encoder, 32768);
 }
 else if ((count == 65535) && (direction == LL_TIM_COUNTERDIRECTION_DOWN))
 {
 Encoder_Position_Offset[Motor] += 32769;
 LL_TIM_SetCounter(Encoder, 32768);
 }
 LL_TIM_ClearFlag_UPDATE(Encoder);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Repeat after me 'I must not fear the libraries. Fear is the mind killer. I must not fear the libraries.

https://www.youtube.com/watch?v=A54yfyi00dI

.'