/*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.