cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476 -- How to have a continuous timer that upon a button push can load a Compare Register with a debounce value and then generate an IRQ?

SWenn.1
Senior III

Hello....

I have TIM1 clocking at 1ms. It rolls over at 1000 counts (ie 1 second). Within the pushbutton IRQ I add 50 to the timer register and disable the GPIO IRQ. I would also like to enable a compare IRQ here as well, such that after the counter counts 50ms it generates a compare IRQ at which point I will re-enable the GPIO IRQ and set a flag for main.

I used LL code to set the timer and disable the GPIO IRQ but don't know exactly what registers to touch to enable the compare IRQ....can someone please tell me how to do this?

I do not want to have a timer that gets enabled in the GPIO IRQ and counts for 50 then generates an interrupt as I want to make use of a continuous timer that is running at 1ms and rolls every second as this is available for other purposes.

Thanks

14 REPLIES 14
gbm
Lead III

In almost every piece of microcontroller software we use some periodic timer. In almost all Cortex-M projects we have SysTick programmed for 1kHz interrupts. In almost every program we also need to do something with smaller frequency, lets say 50 Hz. So, simply put the following code in SysTick_Handler (or any other periodic timer interrupt service):

static uint8_t div_20ms;
if (++div_20ms == 20)
{
    div_20ms = 0;
    // here comes the famous code for button handling - 5 lines
    static bool was_pressed;
    bool is_pressed = ~BTN_GPIO->IDR & BTN_Msk;
    if (is_pressed & !was_pressed)
        handle_button_pressed();
    was_pressed = is_pressed;
}

Well, it's 5 lines, not 4 - my mistake.

Now, dear Mr Karl, please compare your code using EXTI and timer interrupt with the code above which you kindly referred to as "bs" and explain to me and other participants of this forum in which aspects the solution with 2 interrupts is better: programmer's effort (length of code source text), memory footprint, clarity, number of MCU peripheral modules needed?

As far as I can see, your "non-bs" solution requires EXTI and a dedicated timer channel. What you call "bs" uses only an already-used timer timebase interrupt.

As I wrote a few times before, there is an exception to my "rule #1". It's when you use deeper sleep modes of the MCU.

SWenn.1
Senior III

Thank you all so much for the support! I am new to the STM32 world and it is nice to see support on these parts. As a HW person who has had to learn FW (my focus has always been MSP430) I am sure my coding is not up to par and trying to wrap my head around the HAL stuff is somewhat challenging.

gbm
Lead III

You are welcome. Save your time and ditch the HAL. (Hope nobody from ST will see it.) 😉 My code doesn't use HAL and isn't particularly STM32-specific. I work with many different micros, few years ago I also used MSP430 in some projects, that was before the Cortex-M 32-bit era. 🙂

Karl Yamashita
Lead II

@gbm​ I'm just saying it's bs telling people to never use EXTI when in fact you can. Telling people to never using EXTI is not the solution but instead we should try to give a solution. I''ve no quarrels over your code and it's small footprint. And it's nice that you've shared it so others can gain new knowledge.

I'm also sharing my code which can be used for any microcontroller as well. Is it a small footprint? By means no way. However it does make it easier to do a lot more tasks than just debouncing a button which was the point of me showing the different examples. You've might secretly use some of the ideas yourself 😋

If you find my answers useful, click the accept button so that way others can see the solution.
gbm
Lead III

Oh, of course you may and can use as many different interrupts for the simple task of checking the button state as you want. There are some other candidates besides EXTI: USB and ADC being the most obvious ones. I just said there is no point in using EXTI because in any case you MUST also use timer interrupt, and you can achieve the same effect with significantly reduced source code size and complexity by using ONLY the timer interrupt, without engaging EXTI at all.