dev_eng
dev_eng

Reputation: 126

STM32 Timer Output compare not working proper

I am using STM32L476 Nucleo board and STM32CubeMX. I want to use Output Compare channel 1 for timeout of 2 ms. I have configured the timer, but the timer is not giving interrupts for Output Compare. I am getting interrupts for the period I gave to the timer, but not for output compare.

Here is my timer configuration:

static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = TIMER1_PRESCALER_VAL;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = TIMER_PERIOD;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
  sConfigOC.Pulse = 1000 * TIMER_OC_1_VAL;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.BreakFilter = 0;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
  HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

I tried changing the sConfigOC.Pulse value but I don't see the expected behavior.

Upvotes: 2

Views: 6486

Answers (3)

YvonBlais
YvonBlais

Reputation: 125

First, you have to initialize the output pin before starting the timer like that:

/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);

/* USER CODE BEGIN TIM1_Init 2 */
HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);

Second, you have to start the Output timer

HAL_TIM_OC_Start_IT( &htim1, TIM_CHANNEL_1 );
HAL_TIM_Base_Start_IT( &htim1 );

Yyour output pin are enable like that: (this code is for Stm32F4xx)

GPIO_InitStruct.Pin = GPIO_PIN_9; // channel 1
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

I am not sure you need the BREAK code. Have a look 17.3.12 Using the break function in the Reference Manual

Upvotes: 0

Johannes Natter
Johannes Natter

Reputation: 1

Try to replace "TIM_IT_CC1" with "TIM_CHANNEL_1".

Upvotes: 0

Julian
Julian

Reputation: 13

Do you check for the right interrupt flag in the interrupt handler? Also keep in mind that you have to clear the flag right away.

My IRQHandler looks like this, if this is any help for you.

void TIM3_IRQHandler(void) {

    if(LL_TIM_IsActiveFlag_CC1(TIM3) == 1) {
        LL_TIM_ClearFlag_CC1(TIM3);
        TimerCaptureCompare_Callback();
    }
}

Edit:

OK as it seems, the HAL_TIM_OC_DelayElapsedCallback interrupt is only fired when the timer overflows (i. e., resets). This means that you have to enable the overflow interrupt, as the HAL_TIM_OC_Start_IT only enables the capture/compare interrupt. You only need to enable it before enabling the timer.

__HAL_TIM_ENABLE_IT(&tim3, TIM_IT_UPDATE );

Upvotes: 1

Related Questions