Author Topic: Timer help on STM32  (Read 3093 times)

0 Members and 1 Guest are viewing this topic.

Offline WillHuangTopic starter

  • Contributor
  • Posts: 47
Timer help on STM32
« on: October 30, 2017, 03:30:00 pm »
Hello all,
I'm trying to get a basic timer going. What I would like to do is generate an interrupt each time an overflow happens or a compare match occurs. I can get into the interrupt handler, but I can't seem to clear the interrupt flag. As a result, I just stay in the handler mode.

I am using the nucleo-f411re board, and using the internal 16 MHz clock.

This is my code:
Code: [Select]
#include "stm32f4xx.h"                  // Device header

volatile uint32_t ticks = 0;
int main(void)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
   
    /* GPIO */
    GPIOA->MODER |= (0x01 << GPIO_MODER_MODE5_Pos);
   
   
    /* Timer */
    TIM2->CR1 = 0;
    TIM2->CR2 = 0;
   
    TIM2->PSC = 0;
    TIM2->ARR = 10000;
    TIM2->CCR1 = 9999;
   
    TIM2->SR = 0;
   
    NVIC_ClearPendingIRQ(TIM2_IRQn); 
    NVIC_EnableIRQ(TIM2_IRQn);      // Enable TIM2 Interrupt
   
    TIM2->DIER |= (TIM_DIER_UIE | TIM_DIER_CC1IE); // Ebable update event and compare match interrupt
    TIM2->CR1 |= TIM_CR1_CEN;   // Enable timer
   
   
    for(;;)
    {
    }
   
   
    return 0;
}

void TIM2_IRQHandler(void)
{
    if((TIM2->SR & TIM_SR_UIF) || (TIM2->SR & TIM_SR_CC1IF))
    {
        TIM2->SR &= ~(TIM_SR_UIF | TIM_SR_CC1IF); // Clear interrupt flags
        ticks++;
        GPIOA->ODR ^= GPIO_ODR_OD5;
    }
}

What am I doing wrong?
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: Timer help on STM32
« Reply #1 on: October 30, 2017, 04:26:30 pm »
You need to also:

Code: [Select]
NVIC_ClearPendingIRQ(TIM2_IRQn);

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Timer help on STM32
« Reply #2 on: October 30, 2017, 04:34:33 pm »
You need to also:

Code: [Select]
NVIC_ClearPendingIRQ(TIM2_IRQn);

He doesn't need to clear the NVIC bit in the handler. That happens automatically.

https://electronics.stackexchange.com/questions/114985/to-clear-or-not-to-clear-arm-cortex-m-nvic-interrupt-pending

If the core just re-enters the TIM2 handler again, take a look at the TIM2 registers (in a debugger) to see what's keeping the IRQ active.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: Timer help on STM32
« Reply #3 on: October 30, 2017, 04:42:43 pm »
You need to also:

Code: [Select]
NVIC_ClearPendingIRQ(TIM2_IRQn);

that isn't needed, clearing it in the timer is enough

the only obvious difference from something I know works is using &= rather than just write to the status register
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Timer help on STM32
« Reply #4 on: October 30, 2017, 05:53:12 pm »
You need to also:

Code: [Select]
NVIC_ClearPendingIRQ(TIM2_IRQn);

that isn't needed, clearing it in the timer is enough

the only obvious difference from something I know works is using &= rather than just write to the status register
True on both counts.

Just to make sure, I reproduced the code on a F103 (different core, but exactly the same timer 2), and it works as expected.
I also moved the port toggling within the for(;; ) loop, with a condition on ticks, so the code is definitely not stuck in the ISR.

The code, as written, is a bit strange: the difference between the ARR and CCR1 register is just one, so by the time the ISR is entered and the if() is reached, also UIF is set (together with CC1F) and then both are reset.
The capture, then, has no real effect on this program.

Another hint: to simplify debugging, it is convenient to set DBG_TIM2_STOP bit in the DBGMCU_APB1_FZ register, so that the timer is stopped when the core is halted.
« Last Edit: October 30, 2017, 07:08:18 pm by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline WillHuangTopic starter

  • Contributor
  • Posts: 47
Re: Timer help on STM32
« Reply #5 on: October 30, 2017, 11:12:22 pm »
Hi all, thanks for your input. It's working now.

Another hint: to simplify debugging, it is convenient to set DBG_TIM2_STOP bit in the DBGMCU_APB1_FZ register, so that the timer is stopped when the core is halted.
Thanks so much for the hint, great option. I can see the status register changing!


 

Offline mbless

  • Regular Contributor
  • *
  • Posts: 227
  • Country: 00
Re: Timer help on STM32
« Reply #6 on: October 31, 2017, 12:03:05 pm »
Hi all, thanks for your input. It's working now.

Explain what you changed to make it work! Solved threads without solutions are  |O
 

Offline donotdespisethesnake

  • Super Contributor
  • ***
  • Posts: 1093
  • Country: gb
  • Embedded stuff
Re: Timer help on STM32
« Reply #7 on: October 31, 2017, 01:47:15 pm »
I assume when people don't give a reason it's because of a daft mistake they are too embarrassed to mention.  ;D
Bob
"All you said is just a bunch of opinions."
 

Offline WillHuangTopic starter

  • Contributor
  • Posts: 47
Re: Timer help on STM32
« Reply #8 on: October 31, 2017, 05:58:27 pm »
Hi all, thanks for your input. It's working now.

Explain what you changed to make it work! Solved threads without solutions are  |O

Sorry!

It was newbrain's tip that helped. When I was stepping through the code, I could not see the status register change even after writing zero to it. After setting the debug bit, I can see the registers are changing.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf