2025-12-10 9:15 AM
I want to stop generating a PWM signal after 22 clock edges. It seems like the TIMx_RCR register (repetition counter register) should work for this.
My code started from the CubeMX generated code but I have had to remove a lot of it for performance reasons. I am running an STM32H523 with a SYSCLK of 250MHz. The PWM is about 650 KHz so I need to disable the output about 33 us after I start it. That timing is a little tight to do with an interrupt counting down from 22 to zero; however, that seems to be exactly what the TIMx_RCR register does in hardware.
My current code uses the HAL_TIM_PWM_PulseFinishedCallback() function but it seems that it is being called for every pulse, not every 22 pulses.
Does anyone have some pointers or code examples for how to setup TIM1 on an STM32H523? I am using STM32CubeIDE v 1.19.0 (because 2.0.0 broke my build).
Solved! Go to Solution.
2025-12-10 1:27 PM - edited 2025-12-10 1:34 PM
I'm not sure if it is considered bad form to reply to your own question but here is how I solved this problem.
1) Changed TIM1_UP_IRQHandler() in stm32h5xx_it.c to be __weak
/**
* @brief This function handles TIM1 Update interrupt.
*/
__weak void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
/* USER CODE END TIM1_UP_IRQn 1 */
}
2) Added my own interrupt handler in my own file:
void TIM1_UP_IRQHandler( void )
{
SONAR_state = SONAR_PING_LISTEN;
__HAL_TIM_CLEAR_FLAG( &htim1, TIM_FLAG_UPDATE);
HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_1 );
HAL_TIMEx_PWMN_Stop( &htim1, TIM_CHANNEL_1 );
return;
} // end of TIM1_UP_IRQHandler()
3) Enabled the Update interrupt without using HAL_TIM....IT() function:
// Setup TIM1_CH1 (PA8) TXPULSE_B and TIM1_CH1N (PA7) TXPULSE_A for Sonar output pulse transformer
HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1 );
HAL_TIMEx_PWMN_Start( &htim1, TIM_CHANNEL_1 );
// Enable TIM1 Update interrupt
__HAL_TIM_ENABLE_IT( &htim1, TIM_IT_UPDATE);
while( SONAR_state == SONAR_PING_ACTIVE )
{
asm( "nop" ); // NOP
}
// Finished sending ping
TIM1->CR1 &= ~TIM_CR1_CEN; // The __HAL_TIM_DISABLE disable call is kind of large
__HAL_TIM_DISABLE_IT( &htim1, TIM_IT_UPDATE);4) Stopped TIM1 when the flag was set in the interrupt handler (line 15 above)
One downside of this solution is that I had to change a generated file within the auto-generated section so it will break if I regenerate the code from the .ioc file. The resulting waveform (from the transducer side of the transformer) is below.
2025-12-10 1:27 PM - edited 2025-12-10 1:34 PM
I'm not sure if it is considered bad form to reply to your own question but here is how I solved this problem.
1) Changed TIM1_UP_IRQHandler() in stm32h5xx_it.c to be __weak
/**
* @brief This function handles TIM1 Update interrupt.
*/
__weak void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
/* USER CODE END TIM1_UP_IRQn 1 */
}
2) Added my own interrupt handler in my own file:
void TIM1_UP_IRQHandler( void )
{
SONAR_state = SONAR_PING_LISTEN;
__HAL_TIM_CLEAR_FLAG( &htim1, TIM_FLAG_UPDATE);
HAL_TIM_PWM_Stop( &htim1, TIM_CHANNEL_1 );
HAL_TIMEx_PWMN_Stop( &htim1, TIM_CHANNEL_1 );
return;
} // end of TIM1_UP_IRQHandler()
3) Enabled the Update interrupt without using HAL_TIM....IT() function:
// Setup TIM1_CH1 (PA8) TXPULSE_B and TIM1_CH1N (PA7) TXPULSE_A for Sonar output pulse transformer
HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1 );
HAL_TIMEx_PWMN_Start( &htim1, TIM_CHANNEL_1 );
// Enable TIM1 Update interrupt
__HAL_TIM_ENABLE_IT( &htim1, TIM_IT_UPDATE);
while( SONAR_state == SONAR_PING_ACTIVE )
{
asm( "nop" ); // NOP
}
// Finished sending ping
TIM1->CR1 &= ~TIM_CR1_CEN; // The __HAL_TIM_DISABLE disable call is kind of large
__HAL_TIM_DISABLE_IT( &htim1, TIM_IT_UPDATE);4) Stopped TIM1 when the flag was set in the interrupt handler (line 15 above)
One downside of this solution is that I had to change a generated file within the auto-generated section so it will break if I regenerate the code from the .ioc file. The resulting waveform (from the transducer side of the transformer) is below.
2025-12-11 12:05 AM
I personally consider it excellent form to post the solution to a problem, because you never know how it might help others. So kudos to you!
2025-12-11 1:05 AM
Hello,
@StevenG wrote:
I'm not sure if it is considered bad form to reply to your own question but here is how I solved this problem.
That's the first role of the community: to share the solutions and the answers to the questions so others can serve themselves. That's a good practice to provide the answers to your questions and mark them as solutions.