cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G474 TIM1 Update Event Triggered Twice In a Row and Channels Enable Was Delayed

JY.1
Associate II
void TIM1_UP_TIM16_IRQHandler (void) {
  volatile uint8_t  t;
  uint32_t          sr;
 
  sr = TIM1->SR;
  sr &= ~TIM_SR_UIF;
  gpio_set(TIM1_PORT, TIM1_PIN);
  gpio_clr(TIM1_PORT, TIM1_PIN);
  TIM1->SR = sr;
  while (TIM1->SR & TIM_SR_UIF);
}

Above is the code for TIM1 Update Event Interrupt Handler. My repetition counter register TIM1_RCR value is set to 1, and I configured this to be center-aligned PWM mode.

I am triggering TIM1_PORT/TIM1_PIN GPIO just to see the interrupt happening on the logic analyzer, and I expected to see this happens every twice when overflow/underflow happens (RCR is 1)

However, as shown in the picture attached, this interrupt happens "twice in a row" IF above line 10 while loop is commented out? And when it is not commented out, it only appears once.

0693W000006H8t2QAC.png 

So the question is why did this delay happen when trying to clear the status register TIM1_SR?

Also, from this picture below, the red arrow shows that in the very beginning, when the first interrupt of Update Event happens, no Channel PWM was shown from the output pins. These channels were enabled by writing to the CCER register and BDTR register MOE bit before NVIC of this update event interrupt was even enabled.

 0693W000006H8t7QAC.pngDoes this channel enable also require delay and why?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions

> interrupt happens "twice in a row"

Here's why.

> when the first interrupt of Update Event happens, no

> Channel PWM was shown from the output pins

Don't you set TIMx_EGR.UG during timer setup?

JW

View solution in original post

9 REPLIES 9

> interrupt happens "twice in a row"

Here's why.

> when the first interrupt of Update Event happens, no

> Channel PWM was shown from the output pins

Don't you set TIMx_EGR.UG during timer setup?

JW

TDK
Guru

> sr = TIM1->SR;

> sr &= ~TIM_SR_UIF;

> TIM1->SR = sr;

If you just want to clear the update flag, you should do only:

TIM1->SR = ~TIM_SR_UIF;

Doing a read-modify-write on that can have other effects.

> while (TIM1->SR & TIM_SR_UIF);

What is your intention with this statement? As written, the code will block forever if the update is triggered, since nothing will clear it as you're already in the IRQ handler. Setting RCR to 1 is fine, but if the timer is so fast your code can't keep up, that's not so good.

Would have been nice to show the timer setup. Not sure I really follow what you're showing in the plots.

If you feel a post has answered your question, please click "Accept as Solution".
baruch
Associate II

@TDK​ Before answering, try to understand the subject of the question first, maybe ask for some clarification. Then it would be helpful to read other replies. Well, unless your goal is just to make a post...

As a side note, the only line of code you have provided is NOT necessarily correct: it clears all the flags but that may be not always an intent. That brings us back to trying to understand the subject first.

PS: Sorry, my bad. Mistakes do happen: read as TIM1->SR = ~TIM1->SR;

> As a side note, the only line of code you have provided is NOT necessarily correct: it clears all the flags but that may be not always an intent.

No, that clears only one flag, TIM_SR_UIF.

Whatever the OP's intent, RMW to status registers with rc_w0/rc_w1 bits is universally wrong.

And, TDK is right in this:

while (TIM1->SR & TIM_SR_UIF);

is dangerous.

The OP obviously thought the flag is not cleared fast enough, that being the reason for the ISR to reenter.

JW

JW

> PS: Sorry, my bad. Mistakes do happen

In which case its usually best to be polite/professional regardless so that when you are wrong, it's less awkward.

> Before answering, try to understand the subject of the question first, maybe ask for some clarification.

I think the advice I wrote is helpful, and I did ask a question to get further clarification, which you did not answer.

I don't know, I'm happy to ignore your posts if that's what you want.

Good luck.

If you feel a post has answered your question, please click "Accept as Solution".

> In which case its usually best to be polite/professional 

That is exactly what JW did.

I thought you were the OP. I'm just going to ignore the noise here.

If you feel a post has answered your question, please click "Accept as Solution".

And don't create an extra noise pls.

Thanks for sharing the website and I find it very informative regarding all the gimmicks of STM32. And the example I provided was just a way to see if that indeed writing to SR was delayed and thus causing the issue. Obviously it is generally not a good practice to loop like that in the interrupt handler.

Anyways, setting up the TIMx_EGR.UG forcing TIM1 to set to zero before I start all channels did help. Thanks for the tips!