cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with timer interrupt STM32F427Vit6 (TIM14)

DIvan.1
Associate III

Hi everyone!

In my program I have an input which is turning on and off. If the input is not turn on in 3 second I need to detect this. I'm using Timer14 with interrupt. If the input is turn on, the timer is stopped, reseted and start counting from the beginning. If not (timer count to the end) the timer SHOULD give me an interrupt.

My problem interrupt. When I start the timer, It immediately gave me the interrupt after that I never get interrupt from timer again.

In my code I use:

HAL_TIM_Base_Start_IT(&htim14);		// Start timer
 
__HAL_TIM_SET_COUNTER(&htim14, 0); // Reset tiemr if input was turnOn
 
HAL_TIM_Base_Stop_IT(&htim14);  // Stop counter

Did I missed something... maybe interrupt flag reset? or something else?

Thank you for any answer.

Best wishes,

Domen

8 REPLIES 8
TDK
Guru

Prior to starting the timer, but after initialization, clear the update flag.

__HAL_TIM_CLEAR_IT(&htim14, TIM_IT_UPDATE);

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

Thank you for the answer. So If I understand you correct, I need to use __HAL_TIM_CLEAR_IT(&htim14, TIM_IT_UPDATE) everytime after the interrupt occur?

All the best,

Domen

TDK
Guru

No, just prior to starting the timer, but after initialization.

It is cleared within HAL_IRQHandler.

If you're implementing your own IRQ handler then yes you'll need to clear it.

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

The reason to clear the update flag is, that

  • TIMx_PSC is preloaded, i.e. the actual prescaler does not change when written, only after an Update event occurs
  • Update typically occurs at the timer overflow, so the first timer period would not run according to the set prescaler
  • Cube and other "libraries" compensate for this by forcing the Update event by setting TIMx_EGR.UG
  • this causes Update event, which not only loads the prescaler value from the intermediate "holding" to "working" prescaler register, but also sets TIMx_SR.UIF as normal overflow-caused Update would
  • when you enable the Update interrupt, as TIMx_SR.UIF is already set, the interrupt is immediately executed

JW

DIvan.1
Associate III

Thank you for your time and explanation but I'm still a bit confused.

I use CubeMX and HAL library, so the timer is initialize automatically in section /* Initialize all configured peripherals */.

While the execution of my program I Start and Stop (HAL_TIM_Base_Start_IT and HAL_TIM_Base_Stop_IT) the timer for several times.

Do I need to to use __HAL_TIM_CLEAR_IT everytime before start the timer again?

Best,

DomenI

I don't use Cube, but it's open source, so you can look up what do the functions you mention, actually do.

You can also single-step them in the debugger and observe, if the interrupt flags get set - but be sure to set the respective bits in DBGMCU to avoid running of the timers during debugging.

JW

What actually __HAL_TIM_CLEAR_IT (&htim14, TIM_IT_UPDATE) is really doing? If I would like to do it in CMSIS what should I do ?

Pavel A.
Evangelist III

@yabool2001 As Jan wrote, the Cube library is opensource and you're welcome to have a look.

 If I would like to do it in CMSIS what should I do ?

Short answer: look at the ST libraries and examples and do the same.

The timers are vendor-specific (ST) devices, memory-mapped. To access vendor defined memory areas CMSIS does not define anything special and relies on the "common sense" of C compilers. Device registers are declared as volatile structures. All decent compilers for ARM know what means volatile and do what one could expect. Often you can see in the ARM own CMSIS source device writes followed by __DSB(). __DMB() is another CMSIS memory barrier you need to know about.  The ST library uses the same for writes to vendor device registers - plain C read/writes to registers and barriers - but the barriers alone may be not providing enough delay in many cases. It has been disused in this forum. TL;DR

ST library also has macros (READ_REG, WRITE_REG, MODIFY_REG...) which are trivial, except of their ATOMIC variant (ATOMIC_MODIFY_REG...).