0

I've been attempting to work with an encoder on my ARM STM32F0 chip and have been having 0 luck.

First I went down the InputCapture using the CaptureCallback and some subtraction but that produced almost random results. Since I found out there is an encoder library inside of the HAL code so I should just be able to slap that in and happy days. Example 1 2 3

I've implemented each of these different methods and they all cripple on the same fact. TIMx->CNT does not return some counting register but instead returns the pin state. It's as if the HAL library is not properly configuring the Internal Counter but it's also possible I am just making a mistake. If someone could guide me I would greatly appreciate it. Below I pasted some of my config/examples so as to help show what I am doing.

Setup

  Tim_ENCHandle.Instance = TIMENC;
  Tim_ENCHandle.Init.Period = 0xFFFF;
  Tim_ENCHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
  Tim_ENCHandle.Init.Prescaler = 0;
  Tim_ENCHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  encConfig.EncoderMode = TIM_ENCODERMODE_TI12;

  encConfig.IC1Filter = 0x0F;
  encConfig.IC1Polarity = TIM_INPUTCHANNELPOLARITY_RISING;
  encConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  encConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;

  encConfig.IC2Filter = 0x0F;
  encConfig.IC2Polarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  encConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  encConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;


  if (HAL_TIM_Encoder_Init(&Tim_ENCHandle, &encConfig) != HAL_OK) {
    Error_Handler();
  }

  if(HAL_TIM_Encoder_Start_IT(&Tim_ENCHandle,TIM_CHANNEL_ALL)!=HAL_OK){
    Error_Handler();
  } 

defines:

/* Definition for TIMENC clock resources */
#define TIMENC                           TIM2
#define TIMENC_CLK_ENABLE()              __HAL_RCC_TIM2_CLK_ENABLE()

#define TIMENC_CHANNEL_GPIO_PORT()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define TIMENC_GPIO_PORT                 GPIOA
#define TIMENC_GPIO_PIN_CHANNEL1         GPIO_PIN_1
#define TIMENC_GPIO_AF_TIMx              GPIO_AF2_TIM2

#define TIMENC_IRQn                      TIM2_IRQn
#define TIMENC_IRQHandler                TIM2_IRQHandler

MSP:

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) {
 GPIO_InitTypeDef GPIO_InitStruct;
  TIMENC_CLK_ENABLE();
  TIMENC_CHANNEL_GPIO_PORT();

  GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = TIMENC_GPIO_AF_TIMx;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  HAL_NVIC_SetPriority(TIMENC_IRQn, 0, 1);

  HAL_NVIC_EnableIRQ(TIMENC_IRQn);
}

Grab data which is only returning pin state

transmitBufferSize = snprintf((char *)aTxBuffer, 64, "cnt: %d\n\r", TIMENC->CNT);

Datasheet for my specific chip

Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
arduic
  • 659
  • 3
  • 12
  • This one worked for me: https://electronics.stackexchange.com/a/296093/56348 for a standard optical encode with A and B signals. – Bence Kaulics Apr 29 '18 at 09:54
  • I actually saw your answer earlier and gave it a try. Currently I have TIM3 for a PWM driver but I did a similar setup with TIM1. For some reason the internal counter part of my setup is not counting but instead just reading the pin state. I've tried a few things to make the counter well count but the encoder library never works (plane timer worked kind of). To test I hooked up a button to one of the GPIO and read the value of CNT, it's always 0 or 1 based on pin state. Also correct if wrong but I thought the point of the encoder library was to not require a second TIM for timing? – arduic Apr 30 '18 at 01:31

1 Answers1

0

For those that face a similar problem I discovered the solution.

GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2;

Should instead be

GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;

From the STM datasheet and the HAL library notes.

PA0 - TIM2_CH1_ETR

PA1 - TIM2_CH2

PA2 - TIM2_CH3

PA3 - TIM2_CH4

HAL_StatusTypeDef HAL_TIM_Encoder_Start ( TIM_HandleTypeDef * htim, uint32_t Channel )

Starts the TIM Encoder Interface. Parameters: htim : TIM Encoder Interface handle Channel : TIM Channels to be enabled This parameter can be one of the following values: •TIM_CHANNEL_1: TIM Channel 1 selected
•TIM_CHANNEL_2: TIM Channel 2 selected
•TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected

Apparently, what this note in the HAL library was trying to tell me is that the encoder module only works on channels 1 and 2. Channels 3 and 4 do not work with the encoder library. However, it seems this limitation is arbitrarily limited in the HAL library implementation because the only mention of encoder support on the STM32 datasheet is this.

These timers are capable of handling quadrature (incremental) encoder signals and the digital outputs from 1 to 3 hall-effect sensors

arduic
  • 659
  • 3
  • 12