Skip to main content
stenasc
Associate III
March 10, 2013
Question

Debouncing interrupts

  • March 10, 2013
  • 14 replies
  • 3515 views
Posted on March 10, 2013 at 23:38

Hi,

In our system, we are trying to debounce switches on GPIO lines. Every msec the switch is sampled using TIM3. After 16 ticks, if the input has settled, the idea is to set the interrupt pending register and trigger the interrupt.

E.g.simple code to illustrate

if (db_count = 16)

   EXTI->PR = 0x00000200;

else

  EXTI_ClearITPendingBit(EXTI_Line9);

Is this code valid. ie Can I manually set the interrupt pending register like this. When I use this method, I never see the pending reg being set at all. Is there anything else I need to do in order to set this reg?

Many Thanks

Bob
    This topic has been closed for replies.

    14 replies

    Andrew Neil
    Super User
    March 11, 2013
    Posted on March 11, 2013 at 08:41

    ''After 16 ticks, if the input has settled, the idea is to set the interrupt pending register and trigger the interrupt''

    Taking a step back, why do you want to trigger another interrupt? At this point, you have a debounced event - why not just use it?!

    http://www.catb.org/~esr/faqs/smart-questions.html#goal

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    trevor23
    Associate III
    March 11, 2013
    Posted on March 11, 2013 at 11:17

    > if (db_count = 16)

    Shouldn't that be

    if (db_count == 16)

    emalund
    Associate III
    March 11, 2013
    Posted on March 11, 2013 at 15:22

    the way I do switches (and it works)

    global (for module?) switch state

    global (for module?) action flag

    TIMER_ISR (frequency set to ''bounce time'' - typically 10ms)

    new switches = read switches()

    if switch state == new switches return

    if old switches == new switches set switch state and set action flag

    old switches = new switches
    stenasc
    stenascAuthor
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 09:12

    Sorry Trevor...yes I meant that...typo

    stenasc
    stenascAuthor
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 09:15

    Thanks for that Eric...I don't quite follow the logic.

    What is happening at each of these lines.

    Bob

    frankmeyer9
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 09:31

    There are of course several tested approaches that works well.

    But IMHO, a sampling period of 1ms for manually operated keys is too high. It is really difficult to produce a keypress of less than 50ms, at least for a normal human.

    We have commercial products were 10ms or 20ms cycles work well. And at that frequency, you could even think about polling your keys, perhaps from a SysTick interrupt.

    stenasc
    stenascAuthor
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 14:48

    Hi Eric,

    I meant to post the lines that I didn't understand...

    if switch state == new switches return

    if old switches == new switches set switch state and set action flag

    What exactly are you checking for in each of these lines? 

    Regards

    Bob 

    emalund
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 15:49

    global (for module?) word switch state what the main() see

    global (for module?) bool action flag tell the main()that switches have changed

    TIMER_ISR (frequency set to ''bounce time'' - typically 10ms)

    word new switches the result of reading the switches at6 the beginning of the ISR

    word old switches what was read last time in the ISR

    new switches = read switches()

    if switch state == new switches return

    if old switches == new switches set switch state and set action flag

    old switches = new switches better?

    Eriki

    dthedens23
    Associate
    March 12, 2013
    Posted on March 12, 2013 at 20:29

    I like the www.Ganssle.com  method.

    global volatile uint16_t buttonState = 0;

    in timer callback or ISR

    buttonState = (buttonState << 1) | button;  //where button is 1 or 0, read from pin

    in main loop, switch is bounced when buttonState bits are either all 1 or all 0

    stenasc
    stenascAuthor
    Associate III
    March 12, 2013
    Posted on March 12, 2013 at 22:35

    I understand all the types etc..it is the two lines below that are confusing...

    if switch state == new switches return

    My take on this is,,,

    So if current switch state is the same as new switches...do nothing as the new switches hasn't changed...is this correct?

    if old switches == new switches set switch state and set action flag

    This to me means if the last switch value is the sames as the new switch values, which implies that no switch change has been made.

    Would it not be ...if (old switches ^ new switches) set switch state and set action flag....This would detect a change in the switches.