cancel
Showing results for 
Search instead for 
Did you mean: 

Debouncing interrupts

stenasc
Senior
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
14 REPLIES 14
Andrew Neil
Evangelist
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

trevor23
Associate III
Posted on March 11, 2013 at 11:17

> if (db_count = 16)

Shouldn't that be

if (db_count == 16)

emalund
Associate III
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
Senior
Posted on March 12, 2013 at 09:12

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

stenasc
Senior
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 II
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
Senior
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
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 II
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