Skip to main content
Visitor II
April 16, 2021
Question

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

  • April 16, 2021
  • 9 replies
  • 6076 views

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.

    9 replies

    Super User
    April 16, 2021

    > 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.2Author
    Visitor II
    April 16, 2021

    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.2Author
    Visitor II
    April 16, 2021

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

    Super User
    April 16, 2021

    > 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.2Author
    Visitor II
    April 17, 2021

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

    Thanks very much.

    BMcKe.2Author
    Visitor II
    April 17, 2021

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

    Technical Moderator
    April 22, 2021

    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

    BMcKe.2Author
    Visitor II
    April 22, 2021

    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
    September 19, 2023

    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.

    Visitor II
    April 18, 2023

    Still the same on 1.12.0.

    Thanks for Your help.

    Visitor II
    February 7, 2024

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

     

    Super User
    February 7, 2024

    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