Stephens Micro Systems Pty Ltd
/*Example 1 - design spec:-
Button down = pin high.
Minimum debounce (for both press and release) = 60mS.
Using a 5mS timer interrupt.
Fixed sampling timers, like the one below, have an iteration tolerance of +0, -1. So,
if your debounce time needs to be no less than 60mS, you will need to add 1 to the iteration count.
A 5mS timer makes it 13 (60-65mS debounce), a 10mS timer makes it 7 (30-40mS debounce)...
*/
volatile bool button_down = false;
#define DEBOUNCEDNMASK 0b0001111111111111 /// = 13 bit mask = 2^((60 \ 5) + 1) - 1
#define DEBOUNCEUPMASK DEBOUNCEDNMASK
void timer_5mS_interrupt(void) {
static uint button_samples = 0;
button_samples <<= 1;
if ((my_button_port->input_data_register & my_button_bit) != 0) { // for active low button - change !=0 to ==0
button_samples++;
}
if ((button_samples & DEBOUNCEUPMASK) == 0) {
button_down = false;
}
else if ((button_samples & DEBOUNCEDNMASK) == DEBOUNCEDNMASK) {
button_down = true;
}
}
------ meanwhile, back at main.c -------
extern volatile bool button_down;
main() {
...
if (button_down) {
... handle button down
}
...
}
/*Example 2 - design spec:-
This is similar to Example 1, with a transition state as 'button_press'
Button down = pin high.
Minimum debounce (for both press and release) = 30mS.
Using a 5mS timer interrupt.
Fixed sampling timers, like the one below, have an iteration tolerance of +0, -1. So,
if your debounce time needs to be no less than 30mS, you will need to add 1 to the iteration count.
A 5mS timer makes it 7 (30-35mS debounce).
*/
volatile bool button_pressed = false;
#define DEBOUNCEDNMASK 0b01111111 /// = 7 bit mask = 2^((30 \ 5) + 1) - 1
#define DEBOUNCEUPMASK DEBOUNCEDNMASK
void timer_5mS_interrupt(void) {
static uint button_samples = 0;
static bool button_down = false;
button_samples <<= 1;
if ((my_button_port->input_data_register & my_button_bit) != 0) { // for active low button - change !=0 to ==0
button_samples++;
}
if ((button_samples & DEBOUNCEUPMASK) == 0) {
button_down = false;
}
else if ((button_samples & DEBOUNCEDNMASK) == DEBOUNCEDNMASK) {
if (!button_down) {
button_down = true;
button_pressed = true;
}
}
}
------ meanwhile, back at main.c -------
extern volatile bool button_pressed;
main() {
...
if (button_pressed) {
button_pressed = false; /// acknowledge button_pressed
... handle button press
}
...
}
/*Example 3 design spec:-
Using Example 2 above
Following the debounce, if the button is held down for > 1 second, it repeats 5 times per second.
*/
volatile bool button_pressed = false;
#define DEBOUNCEDNMASK 0b01111111 /// = 7 bit mask = 2^((30 \ 5) + 1) - 1
#define DEBOUNCEUPMASK DEBOUNCEDNMASK
#define INITBUTTONRPT 200 /// initial button press threshold (1 second / 5mS = 200)
#define BUTTONRPT INITBUTTONRPT-40 /// repeat interval (1 second / 5 repeats = 200mS, 200mS / 5mS = 40)
void timer_5mS_interrupt(void) {
static uint button_samples = 0;
static bool button_down = false;
static int button_repeat_cnt = 0;
button_samples <<= 1;
if ((my_button_port->input_data_register & my_button_bit) != 0) { // for active low button - change !=0 to ==0
button_samples++;
}
if ((button_samples & DEBOUNCEUPMASK) == 0) {
button_down = false;
}
else if ((button_samples & DEBOUNCEDNMASK) == DEBOUNCEDNMASK) {
if (!button_down) {
button_down = true;
button_pressed = true;
button_repeat_cnt = 0;
}
else {
if (++button_repeat_cnt >= INITBUTTONRPT) {
button_pressed = true;
button_repeat_cnt = BUTTONRPT;
}
}
}
}
------ meanwhile, back at main.c -------
extern volatile bool button_pressed;
main() {
...
if (button_pressed) {
button_pressed = false; /// acknowledge button_pressed
... handle button press
}
...
}
Please feel free to contact me if you have any questions.