Skip to main content
Associate
August 27, 2026
Question

STM32H5 TIM1 PWM One-Pulse/Finite Pulse Generation Using RCR

  • August 27, 2026
  • 1 reply
  • 25 views

I am using TIM1 CH1 in PWM mode with the TIM1 repetition counter (RCR) to generate a finite number of STEP pulses for a stepper motor. The desired step frequency is calculated from the motor speed, and ARR/CCR1 are configured accordingly. RCR is set to steps - 1 so that the PWM should generate the requested number of periods and then stop.

I am using HAL_TIM_PWM_Start() and the TIM1 update interrupt to detect when the required number of pulses has completed. The update callback is working correctly and HAL_TIM_PeriodElapsedCallback() is being called at the expected completion point.

However, TIM1 CH1 is not generating the PWM pulse train correctly, or in some cases no PWM is visible at all on the output pin. I have tried configuring PSC, ARR, CCR1, RCR and the update event/flags before starting PWM, but I am still unable to get the finite number of PWM pulses reliably.

I have attached my motor_driver.c file for reference. Could you please review the implementation and let me know if I am doing anything incorrectly in the TIM1 PWM and repetition counter configuration?

The TIM1 update callback is working correctly, but I am unable to get the expected finite number of PWM pulses on TIM1 CH1. The PWM is either not generated or is not behaving as expected.

Please review the attached code and let me know what could be causing this issue and whether the implementation approach is correct.

1 reply

ST Technical Moderator
September 1, 2026

Hello ​@Kannika_Mallu 
There are a few possible root causes, and the most likely one is that RCR is written, but no update event is generated afterward to transfer it before PWM starts.

In particular, this part may be the issue:

htim1.Instance->RCR = (uint16_t)(steps - 1U);
RCR is updated after the last update event, it may not take effect unless another update event is forced before starting PWM.

I tried to prepare a cleaner version of the code with this in mind. Some small modifications may still be needed if I misunderstood part of the flow, but it should help validate whether the RCR update sequence is the real cause.

Motor_StopSteps();

Motor_SetDirection(direction);
Motor_SetMicrostep(microstep);
Motor_Enable();

if (Motor_SetSpeed(stepFrequency) != HAL_OK)
{
Motor_Stop();
return HAL_ERROR;
}

/* Program repetition count before start */
htim1.Instance->RCR = (uint16_t)(steps - 1U);

/* Force preload transfer */
__HAL_TIM_GENERATE_EVENT(&htim1, TIM_EVENTSOURCE_UPDATE);

/* Clear any UIF caused by UG */
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_UPDATE);
HAL_NVIC_ClearPendingIRQ(TIM1_UP_IRQn);

/* Ensure counter starts from zero */
__HAL_TIM_SET_COUNTER(&htim1, 0U);

/* Enable update interrupt */
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE);

/* Start PWM */
if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)
{
Motor_Stop();
return HAL_ERROR;
}

BR
Gyessine

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.