Debouncing button with sam3x registers

Hi, I saw in the datasheet that there is a possibility to debounce by setting the right registers.since i don't know how to access registers yet I must ask again on how to do this. And no,I don't want to use debouncing software nor using a capacitor. Thanks in advance Decrux

Hi,

You might get some ideas from a header file with lots of ‘debounce’ mentions, component_supc.h, in:

… \arduino-1.5.1r2\hardware\arduino\sam\system\CMSIS\Device\ATMEL\sam3sd8\include\component

But I’m afraid I don’t yet know how this part of the Arduino 1.5 tree relates to anything else…

Jim

Hello,
I figured it out myself. For those interested:

/* PB26 is digital Pin 22, view Datasheet page 647 */
pinMode(22, INPUT);
digitalWrite(22, HIGH); // Pullup
attachInterrupt(22, myInterruptServiceRoutine, FALLING);
REG_PIOB_IFER |= 1<<26; // Input Filter Enable Register
PIOB->PIO_DIFSR |= 1<<26; // Debouncing Input Filter Select Register
PIOB->PIO_SCDR |= 0xff; // Slow Clock Divider Register

But I would rather use the digital Pin names instead of the Port Pins. Ideas?

Greetings
decrux

Are you sure that will debounce enough? From the data sheet

When the glitch or debouncing filter is enabled, a glitch or pulse with a duration of less than 1/2 Selected Clock Cycle (Selected Clock represents MCK or Divided Slow Clock depending on PIO_SCIFSR and PIO_DIFSR programming) is automatically rejected, while a pulse with a duration of 1 Selected Clock (MCK or Divided Slow Clock) cycle or more is accepted.

So as I read it unless you can get one of those clocks down to a period of say 10-50mS you will not be doing any meaningful debouncing, at least not in the normal context of handling a mechanical switch.

How slow does the Slow Clock get with 0xff in that register?


Rob

There is an array struct called g_APinDescription which contains the port and mask for each Arduino pin number. You use it like this for example:

g_APinDescription[pin].pPort → PIO_SODR = g_APinDescription[pin].ulPin; // equivalent to digitalWrite(pin,HIGH)

Replace ‘PIOx ->’ with ‘g_APinDescription[pin].pPort ->’ and ‘1<<yy’ with ‘g_APinDescription[pin].ulPin’

So for example PIOB->PIO_DIFSR |= 1<<26 would become:
g_APinDescription[22].pPort → PIO_DIFSR |= g_APinDescription[22].ulPin;

from a quick read of the data sheet I think the filter can go as slow as 1 second :slight_smile: At 0xff it’s about 16ms.

Thank you for your answer. How I understood it: g_APinDescription[] is an array of PinDescription structures (from the Arduino.h). PIO_SODR is the Set Output Data Register. "DIV: Slow Clock Divider Selection for Debouncing Tdiv_slclk = 2*(DIV+1)*Tslow_clock." from datasheet page 669 with a slow clock frequency of 32 kHz etc. Your code example is working perfectly.

Your code example is working perfectly.

How did you test it?

from a quick read of the data sheet I think the filter can go as slow as 1 second

That is slow enough :) How do you get such a low freq?

32kHz / 255 is still 128Hz.


Rob

Well I simply replaced
PIOB->PIO_DIFSR |= 1<<26 would become:
g_APinDescription[22].pPort → PIO_DIFSR |= g_APinDescription[22].ulPin;

in my code example for debouncing posted above and the button was debounced.

1 second is what I get by putting DIV = (2¹? - 1) and not 255 in Tdiv_slclk = 2*(DIV+1)*Tslow_clock , see datasheet page 669. The DIVi are the single bits in DIV. slow clock frequency is by default 32 kHz. datasheet page 277. Also T = 1/f etc.

Greetings

Yes I see, so you can get down to 32kHz / 16383 if you want. Nice feature.


Rob

Thanks I missed the REG_PIOB_IFER register in the docs as it was on the previous reg page list and was scratching my head!