Skip to main content
Visitor II
October 21, 2024
Question

Which TIMs support Quadrature encoder

  • October 21, 2024
  • 8 replies
  • 2214 views

Hello,

I am trying to use the quadrature encoder mode of the TIM in the STM32U585VITx, for positioning purposes of a stepper motor movement.
According to DS13086, page 79, the general purpose timers (TIM2, TIM3, TIM4, TIM5, TIM15, TIM16, TIM17) support quadrature encoders.
However, according to RM0456 Rev 5, page 2083, TIM 1.8 has support for quadrature encoders.
Could you please clarify which TIMs support this encoder?

Also, I am currently trying to use TIM8 for this purpose (not sure if it is the right timer), but when I move the motor and read the timer, I just get a bunch of zeros.

Any help would be greatly appreciated,

Thank you

    This topic has been closed for replies.

    8 replies

    Super User
    October 21, 2024

    @Elham wrote:

    According to DS13086, page 79, the general purpose timers (TIM2, TIM3, TIM4, TIM5, TIM15, TIM16, TIM17) support quadrature encoders.


    It also says that TIM1 & TIM8 share many features with the GP Timers - so that could include encoder support

    AndrewNeil_0-1729500834258.png

    The datasheet is really just giving a quick overview - the Reference Manual gives the complete description

     

    ElhamAuthor
    Visitor II
    October 21, 2024

    Thanks for your quick reply Andrew,

    But just saying "Many features are shared with the general purpose TIMx timers" is not enough for me.

    Also, on the 2nd page of the DS13086 it says that only two of the timers support this feature:

    Up to 17 timers and 2 watchdogs:
    - 2 16-bit advanced motor control

    Which I think is inconsistent with the explanations in 3.42.2.

    Thank you

     

    Super User
    October 21, 2024

    Again, the datasheet is really just giving a quick overview - the Reference Manual is the place to find complete details.

    The datasheet is focussed on physical specifications - electrical, mechanical, thermal, etc.

    The RM describes the internal workings of the peripherals.

    ST Employee
    October 21, 2024

    Hello @Elham

    TIM8 can indeed be used for quadrature encoder mode! 

    >> I just get a bunch of zeros. 

    check the TIMx_SMCR register, TI1 and TI2 configuration and ensure that the counter is enabled by setting the CEN bit in the TIMx_CR1 register. 

    Otherwise, you can share some code snippet to try and figure out what's not working or misconfigured..

    Super User
    October 21, 2024

    > According to DS13086, page 79, the general purpose timers (TIM2, TIM3, TIM4, TIM5, TIM15, TIM16, TIM17) support quadrature encoders.

    Well that's not true, partially because ST's nomenclature is not quite right.

    TIM15/16/17 are not the same kind than TIM2/3/4/5 (which in turn form 2 groups themselves, 16-bit and 32-bit) and they don't have encoder mode.

    As @Andrew Neil said above, the definitive guide here is the Reference Manual - for each timer, have a look at its TIMx_SMCR.SMS description - if it does have encoder mode, it is listed there.

    JW

    Graduate II
    October 22, 2024

    Hi,

    You can also look at the Timer diagram.

    Screenshot_20241022_141352.png

     

    Also, the TIMx_ARR register needs to be set to a non-zero value for it to count... Usually, set it to max 0xFFFF (16 bit), or 0xFFFFFFFF (32 bit)...

    Kind regards
    Pedro

    ElhamAuthor
    Visitor II
    October 22, 2024

     

    Thanks all for your hints and help :)

    I am using STM32CubeIDE to configure TIM. I have posted my settings here. I have also included the auto generated tim.c. I have also tried to add some user code to this file, but no difference and I still get a bunch of zeros when I read the encoder like this:

    uint32_t motor_ctl_get_encoder_value()
    {
    return (uint32_t)htim8.Instance->CNT;
    }

     

    Screenshot 2024-10-22 0929371.png

    void MX_TIM8_Init(void)
    {
    
     /* USER CODE BEGIN TIM8_Init 0 */
    
     /* USER CODE END TIM8_Init 0 */
    
     TIM_Encoder_InitTypeDef sConfig = {0};
     TIM_MasterConfigTypeDef sMasterConfig = {0};
    
     /* USER CODE BEGIN TIM8_Init 1 */
    
     /* USER CODE END TIM8_Init 1 */
     htim8.Instance = TIM8;
     htim8.Init.Prescaler = 0;
     htim8.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
     htim8.Init.Period = 65535;
     htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim8.Init.RepetitionCounter = 0;
     htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
     sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
     sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
     sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
     sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
     sConfig.IC1Filter = 10;
     sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
     sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
     sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
     sConfig.IC2Filter = 10;
     if (HAL_TIM_Encoder_Init(&htim8, &sConfig) != HAL_OK)
     {
     Error_Handler();
     }
     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
     sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
     if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN TIM8_Init 2 */
    
     uint32_t tmp = TIM8->CR1;
     tmp = tmp | 0x00000001;
     TIM8->CR1 = tmp;
     sConfig.IC2Selection = TIM_CCMR1_CC2S_0;
    
     /* USER CODE END TIM8_Init 2 */
    
    }

     

    Super User
    October 22, 2024
    ElhamAuthor
    Visitor II
    October 22, 2024

    Thank you Andrew,

    I attached that part of schematic. Pins numbers 63, 64 of the MCU are used for this.

     

    Screenshot 2024-10-22 1039501.pngScreenshot 2024-10-22 1040502.png

    Super User
    October 22, 2024

    Read out and check/post content of TIM and relevant GPIO registers content.

    By reading out GPIOx_IDR check, if the respective bits are toggling when you turn the encoder slowly.

    JW

    PS>

    htim8.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;

    This should be ignored in Encoder mode; but for good measure, set it to default ("edge aligned", I don't know what's the Cube parlance for this).

    ElhamAuthor
    Visitor II
    October 23, 2024

    Thank you for your suggestion,

    I checked GPIOx_IDR and there is no change there while motor moves.

    Super User
    October 23, 2024

    Unless those pins are set as Analog by some mistake, you then have some electrical problem beyond the STM32.

    Start with observing the encoder outputs using preferrably oscilloscope, proceed with checking continuity up to the mcu pins.

    JW