Skip to main content
Neo M
Associate III
Oct 5, 2016 10:39 PM UTC
Question

TIM4 in Encoder Mode - Nucleo F767ZI

Posted on October 06, 2016 at 00:39

I am trying to set up TIM4 in Encoder Mode in Nucleo F767ZI. I used STM32CubeMX to set up the Timer. The TIM->CNT value oscillates between two values. On checking further, I found the DIR bit to be oscillating between 0 and 1. If I read the values of both the channels and do an external counting, it works fine. I am reading both edges on both the channels. 

    This topic has been closed for replies.

    7 replies

    Neo M
    Neo MAuthor
    Associate III
    Oct 6, 2016 8:09 PM UTC
    Posted on October 06, 2016 at 22:09

    This is the TIM4 Init code as generated by Cube:

    /* TIM4 init function */
    static void MX_TIM4_Init(void)
    {
    TIM_Encoder_InitTypeDef sConfig;
    TIM_MasterConfigTypeDef sMasterConfig;
    htim4.Instance = TIM4;
    htim4.Init.Prescaler = 0;
    htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim4.Init.Period = 0xffff;
    htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
    sConfig.IC1Polarity = TIM_ICPOLARITY_BOTHEDGE;
    sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
    sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
    sConfig.IC1Filter = 0;
    sConfig.IC2Polarity = TIM_ICPOLARITY_BOTHEDGE;
    sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
    sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
    sConfig.IC2Filter = 0;
    if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK)
    {
    Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
    {
    Error_Handler();
    }
    }

    And I'm using

    HAL_TIM_IC_CaptureCallback

    to get the interrupts and calculate externally. At the same time I am comparing it to the TIM4->CNT value which doesn't seem to count up or down consistently.

    Andrei Chichak
    Lead
    Oct 7, 2016 5:45 AM UTC
    Posted on October 07, 2016 at 07:45

    I was working on something just like this just last night, but for a 407. 

    Try watching this:

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

    Ignore what he is saying, unless you understand Russian, but he shows all of the steps to do encoders using Cube.

    Andrei from The Great White North
    Walid FTITI_O
    Visitor II
    Oct 7, 2016 8:28 AM UTC
    Posted on October 07, 2016 at 10:28

    HiNeo,

    I think you missed to add the start of Timer Encoder interface by adding the following (as example):

    /* Start the encoder interface */
    HAL_TIM_Encoder_Start(&Encoder_Handle, TIM_CHANNEL_ALL);

    Unfortunaly, the STM32CubeF7 does not contains an encoder example. You would take a look to another STM32Cube package like

    http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef4.html

    which has the example ''TIM_Encoder''at this path: STM32Cube_FW_F4_V1.0\Projects\STM324xG_EVAL\Examples\TIM\TIM_Encoder I will submit a request to add such example in the STM32CubeF7 package. -Hannibal-
    Neo M
    Neo MAuthor
    Associate III
    Oct 7, 2016 12:20 PM UTC
    Posted on October 07, 2016 at 14:20

    Hannibal,

    I am starting the encoder using HAL_TIM_Encoder_Start(). I just posted the Timer initialization part that the Cube generated. 

    The TIM4->CNT value changes, but it keeps going up and down, and so does the DIR bit. I am not sure why it is doing that, when the motor is consistently running in only one direction.

    Thanks.

    Walid FTITI_O
    Visitor II
    Oct 7, 2016 1:54 PM UTC
    Posted on October 07, 2016 at 15:54

    Hi Neo, 

    So try to play on ICpolarity, put one edge (up or down).

    -Hannibal-

    Neo M
    Neo MAuthor
    Associate III
    Oct 7, 2016 2:44 PM UTC
    Posted on October 07, 2016 at 16:44

    Thanks Hannibal!

    It seems to be counting properly now.

    But I am wondering why is it so? Why can't it count properly when the ICPolarity is set to Both Edges?

    Walid FTITI_O
    Visitor II
    Oct 7, 2016 3:43 PM UTC
    Posted on October 07, 2016 at 17:43

    Hi Neo, 

    The both Edge Sensitive case is dedicated for another different encoding type .

    -Hannibal-