/************************************************************************/ /* */ /* Debouncing 8 Keys */ /* Sampling 4 Times */ /* With Repeat Function */ /* */ /* Author: Peter Dannegger */ /* danni@specs.de */ /* */ /************************************************************************/ #pragma cd pl(9999) #include #define KEY_INPUT P2 #define LED_OUTPUT P0 #define REPEAT_MASK 0x0F // repeat only key 0 ... key 3 #define REPEAT_START 125 // after 500ms #define REPEAT_NEXT 25 // every 100ms char key_state; // debounced and inverted key state: // bit = 1: key pressed char key_press; // key press detect or repeat void t0_int( void ) interrupt INT_T0 { static char ct0, ct1, rpt; char i; TH0 |= -16; // interrupt every 4.096ms at 12MHz 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 key_press |= key_state & i; // 0->1: key press detect if( (key_state & REPEAT_MASK) == 0 ) // check repeat function rpt = REPEAT_START; // start delay if( --rpt == 0 ){ rpt = REPEAT_NEXT; // repeat delay key_press |= key_state & REPEAT_MASK; } } #pragma disable // disable interrupts char get_key_press( void ) { char i; i = key_press; // read keys key_press = 0; // clear keys return i; } void main( void ) { key_state = 0; key_press = 0; TMOD = T0_M0_; // T0: 16 bit timer IE = EA_ + ET0_; // global + T0 interrupt enable for(;;) // main loop LED_OUTPUT ^= get_key_press(); // toggle LEDs on key press }