Hello.
After performing a couple of searches for debouncing code here in AVR Freaks community I found this code someone already wrote:
/************************************************************************ ;* * ;* Testing Read and debounce up to 8 keys * ;* Bulletproof: 4 equal samples needed * ;* * ;* Author: P. Dannegger * ;* * ;***********************************************************************/ #include #include #include #define KEY_INPUT PINC #define LED_OUTPUT PORTB #define LED_DIR DDRB char key_state; // debounced and inverted key state: // bit = 1: key pressed char key_press; // key press detect SIGNAL (SIG_OVERFLOW0) { static char ct0, ct1; char i; i = key_state ^ ~KEY_INPUT; // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state // now debouncing finished key_press |= key_state & i; // 0->1: key press detect } char get_key_press( char key_mask ) { cli(); key_mask &= key_press; // read key(s) key_press ^= key_mask; // clear key(s) sei(); return key_mask; } int main( void ) { key_state = 0; key_press = 0; TCCR0 = 1<<CS02; //divide by 256 * 256 TIMSK = 1<<TOIE0; //enable timer interrupt LED_DIR = 0xFF; LED_OUTPUT = 0xFF; sei(); for(;;) // main loop LED_OUTPUT ^= get_key_press( 0xFF ); // toggle LEDs on key press }
I'm now trying to integrate this code in my project code but I'm kind of struggling to understand the chronology of events, I mean what happens and when it happens.
But first things first.
I'm using an AtMega328P and 2 push-buttons attached at pins PD2 (INT0) and PD3 (INT1) and I'm using their interrupts to perform some actions and I need debouncing routine to ensure only one action per button push.
I'm using avrdude 6.3 under Debian 9 to upload the code into the uC and an USB to TTL UART converter to do the upload.
I'm also aware, from this link, that the name vector for TIMER interrupts have changed and I changed
SIGNAL (SIG_OVERFLOW0)
to
ISR (TIMER0_OVF_vect)
I have also changed register names to match my AtMega328P as follows:
TCCR0 = 1<<CS02;
to
TCCR0B = 1<<CS02;
and
TIMSK = 1<<TOIE0;
to
TIMSK0 = 1<<TOIE0;
I also got rid of the LEDs thing because I don't need them, so summarising, this is what my code looks like:
#define KEY_INPUT PIND uint8_t key_state = 0; // debounced and inverted key state: // bit = 1: key pressed uint8_t key_press = 0; // key press detect void get_key_press(uint8_t key_mask){ cli(); key_mask &= key_press; // read key(s) key_press ^= key_mask; // clear key(s) sei(); } void debounce_button_timer_setup(void){ TCCR0B = 1 << CS02; //divide by 256 * 256 TIMSK0 = 1 << TOIE0; //enable timer interrupt sei(); } debounce_button_timer_setup(); get_key_press(0x0c);
This might be a little bit out of context because my project has several files and the code above is in different places, not all together just like I pasted it here.
My struggle is that the push buttons are attached at PD2 and PD3 and they are triggering the INT0 and INT1 interrupts and as the debounce code uses TIMERs to raise their flags to run the debounce code, I'm not sure when and where to use the get_key_press() function.
I might need to show how my INT0 and INT1 vectors code is:
ISR (INT0_vect){ sweep_sta = SWEEP_STA_UP; } ISR (INT1_vect){ sweep_sta = SWEEP_STA_DOWN; }
So this is my code for the interrupts 0 and 1 and this sweep_sta variable is being checked inside the main() function infinite loop, so I'm not quite sure where to use the debounce code functions, I mean the get_key_press() function!
Any help is appreciated! I'm sorry if I'm missing any critical information!
Thanks
PsySc0rpi0n