www.mikrocontroller.net

Text1.c

Text1.c
/************************************************************************/
/*                                                                      */
/*                      Debouncing 8 Keys        */
/*      Sampling 4 Times        */
/*      With Repeat Function        */
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                      danni@specs.de                                  */
/*                                                                      */
/************************************************************************/


#include <reg52.h>
#include <stdio.h>
typedef unsigned char  u8;
#define Timer0L 0xCC     // 1ms Tick bei 22,118 MHz
#define Timer0H 0xF8    // Dezimal 63692

#define Timer1L 0xFD    // 19200 Baud bei 22,118 MHz
#define Timer1H 0xFD

sbit KEY_PIN=P0^2;
#define KEY0    0
#define KEY1    1
#define KEY2    2

#define REPEAT_MASK  (1<<KEY1^1<<KEY2)  // repeat: key1, key2
#define REPEAT_START  500    // after 500ms
#define REPEAT_NEXT    200    // every 200ms


u8 key_state;        // debounced and inverted key state:
              // bit = 1: key pressed
u8 key_press;        // key press detect

u8 key_rpt;
void timer0() interrupt 1            
{
  static u8 ct0, ct1,rpt;
  u8 j;



  j = key_state ^ ~KEY_PIN;    // key changed ?
  ct0 = ~( ct0 & j );      // reset or count ct0
  ct1 = ct0 ^ (ct1 & j);    // reset or count ct1
  j &= ct0 & ct1;      // count until roll over ?
  key_state ^= j;      // then toggle debounced state
  key_press |= key_state & j;    // 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_rpt |= key_state & REPEAT_MASK;
  }

}


u8 get_key_press( u8 key_mask )
{
  TR0=0  ;                    // Timer anhalten
  key_mask &= key_press;                        // read key(s)
  key_press ^= key_mask;                        // clear key(s)
  TR0=1;                    // Timer starten
  return key_mask;
}


u8 get_key_rpt( u8 key_mask )
{
  TR0=0  ;                    // Timer anhalten
  key_mask &= key_rpt;                          // read key(s)
  key_rpt ^= key_mask;                          // clear key(s)
  TR0=1;                    // Timer starten
  return key_mask;
}


u8 get_key_short( u8 key_mask )
{
//cli();      // read key state and key press atomic !
  return get_key_press( ~key_state & key_mask );
}


u8 get_key_long( u8 key_mask )
{
  return get_key_press( get_key_rpt( key_mask ));
}






int main( void )
{
  TMOD = 0x21;         // Timer 1 = 8-Bit-Timer mit Auto-Reload-Modus. 
                // Timer 0 = 16-Bit-Timer. 

   TL1 = Timer1L;        // 19200 Baud bei 22,118 MHz
   TH1 = Timer1H;        // Nachladewert fuer TL1 
   TR1 = 1;             // Timer 1 starten       
   SCON = 0x52;         // Freigabe von Sender und Empfaenger; Betriebsart: Modus 1
  
   TL0 = Timer0L;        // Startwert für Timer0 0x7000
   TH0 = Timer0H;        // dezimal 28672 => Interrupt alle 20ms
   ET0 = 1;          // Timer0 Interrupt einschalten
   EA  = 1;          // Interrupt einschalten
   TR0 = 1;            // Timer 0 starten

 
  for(;;){          // main loop
      // single press

if( get_key_press( 1<<KEY0 ))
      printf("Taste gedrueckt\n");

      // release after short press: task 1
      // long press: task 2

    if( get_key_short( 1<<KEY1 ))
        printf("KURZ\n");

    if( get_key_long( 1<<KEY1 ))
      printf("LANG\n");

      // single press and repeat

    if( get_key_press( 1<<KEY2 ) || get_key_rpt( 1<<KEY2 )){
     printf("wiederholung\n");   
    }

 
  }
}

webmaster@mikrocontroller.net – Impressum – Werbung auf Mikrocontroller.net