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?
> 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.
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 */
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)
void HAL_TIM_Period_ElapsedCallback(TIM_HandleTypeDef *htim)
/* 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 */
/* USER CODE END PFP */
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
/* USER CODE END TIM1_UP_IRQn 1 */
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 */
/* USER CODE END TIM1_Init 2 */
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.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
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.