AnsweredAssumed Answered

Problem reading multiple encoders

Question asked by Nipuni Perera on Mar 5, 2018
Latest reply on Apr 12, 2018 by Nipuni Perera

I am planning to use two encoders determine the position of two motors, to be used for a PID. I am using the STM32F4 Discovery board.

I am using TIM1 to generate PWMs, and so far, all four channels are working without a problem. I am planning to use two of the four other timers with an encoder mode (TIM2, TIM3, TIM4 and TIM8) for reading the encoders. So far, only TIM2 seems to work, though the code is the same for all timers.

I am using the Keil uVision 5 IDE, with code generated from cube, using the HAL libraries. The code is given below. I am including only the main program, TIM initialization functions, and the encoder MspInit Function.

 

Main program: I am using HAL_TIM_Encoder_Start_IT() here, but I initially tried using HAL_TIM_Encoder_Start(), which worked with TIM2. Neither works with any of the other timers. For reading the counter values, I am using TIMx->CNT.

int main(void)
{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */
SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
MX_TIM3_Init();
MX_TIM4_Init();
MX_USART2_UART_Init();

/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 ,GPIO_PIN_SET);

//Turn encoder 1 on
HAL_TIM_Encoder_Start_IT(&htim3,TIM_CHANNEL_ALL);

//Turn encoder 1 on
HAL_TIM_Encoder_Start_IT(&htim4,TIM_CHANNEL_ALL);

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
count=TIM3->CNT;
count_1=TIM4->CNT;

if ((count_1%4)==0){
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_RESET);
}
else if ((count_1%4)==1){
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_RESET);
}
else if ((count_1%4)==2){
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_15,GPIO_PIN_RESET);
}
else if ((count_1%4)==3){
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14,GPIO_PIN_RESET);
}

if (ms>1000){
PutString("count: ");
PutInt(count);
PutString(",count: ");
PutInt(count_1);
PutString("\n");
ms = 0;
}

}
/* USER CODE END 3 */

}

 

 

Timer initialization, TIM3:

/* TIM3 init function */
static void MX_TIM3_Init(void)
{

TIM_Encoder_InitTypeDef sConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65536;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0;
if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}

 

Timer initialization, TIM4:

/* 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 = 65536;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0;
if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}

 

Timer initialization, TIM2. It's not used here, but I included it for reference because it's the only one that worked.

/* TIM2 init function */
static void MX_TIM2_Init(void)
{

TIM_Encoder_InitTypeDef sConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65536;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 5;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 5;
if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}

}

 

Encoder MSP init, for the code using TIM3 and TIM4:

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(htim_encoder->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */

/* USER CODE END TIM3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();

/**TIM3 GPIO Configuration
PC6 ------> TIM3_CH1
PB5 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN TIM3_MspInit 1 */

/* USER CODE END TIM3_MspInit 1 */
}
else if(htim_encoder->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspInit 0 */

/* USER CODE END TIM4_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM4_CLK_ENABLE();

/**TIM4 GPIO Configuration
PB6 ------> TIM4_CH1
PB7 ------> TIM4_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN TIM4_MspInit 1 */

/* USER CODE END TIM4_MspInit 1 */
}

}

 

I will be very grateful for any help you can provide with regards to this issue.

Outcomes