C_tast.c51
/************************************************************************/
/* */
/* Debouncing 8 Keys */
/* Sampling 4 Times */
/* With Repeat Function */
/* */
/* Author: Peter Dannegger */
/* danni@specs.de */
/* */
/************************************************************************/
#pragma cd pl(9999)
#include <reg51.h>
#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
}