Skip to main content
BMcKe.2
Associate II
Apr 16, 2021 7:39 PM UTC
Question

How do I generate a Timer Interrupt at the completion of a series of pulses?

Using an Advanced Timer (Timer 1 in STM32H743ZI) in PWM One-Shot mode, and using the Repetition Counter, I generate a string of 5 pulses. For each pulse, I generate a Capture/Compare Interrupt and have a CallBack routine (using "HAL_TIM_PulseFinishedCallBack(...)". This works fine.

I have also enabled the Update Interrupt for Timer 1 and expected it to service that routine at the completion of the 5 pulses as well but it does not. The code for the Interrupt is generated in the stm32h7xx_it.c file "(void TIM1_UP_IRQHandler(void))" but execution does not appear to reach it. Both Timer 1 Capture/Compare and Update Interrupts are enabled in the NVIC. I am using "void HAL_TIM_Period_ElapsedCallback(...)" as the call back routine for the Update Interrupt.

How do I get the Update Interrupt to work?

This topic has been closed for replies.

12 replies

waclawek.jan
Super User
Apr 16, 2021 9:43 PM UTC

> The code for the Interrupt is generated in the stm32h7xx_it.c file "(void TIM1_UP_IRQHandler(void))" but execution does not appear to reach it.

How do you verify that?

Read out TIM1_DIER and make sure the UIE bit is set in it.

Make sure "TIM1_UP_IRQHandler" is spelled correctly, check that it matches the spelling in the startup code. Check in disasm that this routine's address is present at the correct address in the interrupt vector. Some other interrupt-related hints here.

JW

BMcKe.2
BMcKe.2Author
Associate II
Apr 16, 2021 9:56 PM UTC

I created a small function to Toggle a GPIO output high and then low again to generate a pulse that I can see on an oscilloscope.

I call this function from my HAL_TIM_PWM_PulseFinishedCallBack and the pulse appears in the correct position after each of the 5 pulses. I then call the function from HAL_TIM_Period_ElapsedCallback which I thought would create a final pulse at the end of the pulse train but it doesn't appear.

/* USER CODE BEGIN 4 */

void Marker_Pulse(void)

{

HAL_GPIO_WritePin(GPIOG, GPIO_PIN_4, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOG, GPIO_PIN_4, GPIO_PIN_RESET);

}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

Marker_Pulse();

}

void HAL_TIM_Period_ElapsedCallback(TIM_HandleTypeDef *htim)

{

Marker_Pulse();

Marker_Pulse();

}

/* USER CODE END 4 */

I then placed the Marker_Pulse function inside the Interrupt handler routine to see if it was even being called and I didn't observe any pulse then either. So I made the assumption that the Handler was not being called. (note: The Pulse_Marker function prototype is also defined inside the stm32h7xx_it.c file)

/* Private function prototypes -----------------------------------------------*/

/* USER CODE BEGIN PFP */

void Marker_Pulse(void);

/* USER CODE END PFP */

void TIM1_UP_IRQHandler(void)

{

 /* USER CODE BEGIN TIM1_UP_IRQn 0 */

Marker_Pulse();

 /* 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 */

}

BMcKe.2
BMcKe.2Author
Associate II
Apr 16, 2021 10:19 PM UTC

0693W000008zpWMQAY.jpgThe UIE bit for DIER for TImer 1 is set to zero.

waclawek.jan
Super User
Apr 16, 2021 11:04 PM UTC

> The UIE bit for DIER for TImer 1 is set to zero.

Well, then TIM1_UP_IRQHandler() won't be called.

I don't Cube.

JW

BMcKe.2
BMcKe.2Author
Associate II
Apr 17, 2021 1:50 AM UTC

Now that I know what has to be done I'll figure out a work-around.

Thanks very much.

BMcKe.2
BMcKe.2Author
Associate II
Apr 17, 2021 2:24 AM UTC

Just for reference, the work-around is to write directly to the TIM1 DIER register with the bits set to 1 for CC1IE and UIE to turn on both the Capture/Compare Interrupt and the Update Interrupt.

Place this instruction after the Cube IDE generated code so that it overwrites the incorrect Cube IDE settings.

/* USER CODE BEGIN TIM1_Init 2 */

 TIM1->DIER=0x3;

 /* USER CODE END TIM1_Init 2 */

Amel NASRI
ST Technical Moderator
Apr 22, 2021 12:41 PM UTC

Hi @BMcKe.2​ ,

In order to have UIE bit set in DIER register, you need to call the API HAL_TIM_Base_Start_IT in a USER CODE section. This API is a processing function, not generated by STM32CubeMX or STM32CubeIDE in the initialization code.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
BMcKe.2
BMcKe.2Author
Associate II
Apr 22, 2021 12:53 PM UTC

HAL_TIM_Base_Start_IT does indeed set the UIE bit in the DIER register but I need to generate a PWM pulse output with timer 1, so I can't use HAL_TIM_Base_Start_IT.

When I use HAL_TIM_PWM_Start_IT, it should also set the UIE bit to one but it doesn't. I assume this is a bug in CubeMX.

To fix this, I write directly to the DIER register using TIM1->DIER=0x3; right after the HAL_TIM_PWM_Start_IT instruction. That sets the UIE bit to one and the interrupts then work.

Visitor II
Sep 19, 2023 9:02 PM UTC

You can use the HAL_TIM_Base_Start_IT to start the timer including the PeriodElapsed interrupt, and then use HAL_TIM_PWM_Start to start generate PWM. If you need the compare interrupts too, then use HAL_TIM_PWM_Start_IT.

NRoth.3
Associate
Apr 18, 2023 2:59 PM UTC

Still the same on 1.12.0.

Thanks for Your help.

Visitor II
Feb 7, 2024 11:44 AM UTC

what is  PWM One-Shot mode  and PWM ONE-Pulse mode?? Are both are same or different?

 

waclawek.jan
Super User
Feb 7, 2024 1:18 PM UTC

I don't remember seeing "One-shot" anywhere else but in the opening post here, so it may be misspelling of One-pulse mode.

KW