cancel
Showing results for 
Search instead for 
Did you mean: 

TIM4 in Encoder Mode - Nucleo F767ZI

Neo M
Associate II
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. 

7 REPLIES 7
Neo M
Associate II
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.

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
Senior II
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
Associate II
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
Senior II
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
Associate II
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
Senior II
Posted on October 07, 2016 at 17:43

Hi Neo, 

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

-Hannibal-