Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
07/20/09 09:59
Read: times


 
#167585 - Karas's Keypad Scanner Code In C - detabbed
Responding to: ???'s previous message
Michael Karas said:
the following topic came up as the first hit.
http://www.8052.com/forum/read/88596

The indentation in Karas's Keypad Scanner Code In C (linked from that thread) seems to have gone really wild!
(presumably due to the TABs?)

So here it is in a (hopefully) easier-to-read layout (with the TABs converted to spaces):


#define REPEAT_ENABLE 1         /* set non zero to enable key repeat */
#define KEY_RATE 5              /* Number of calls to key_scan() before 
                                /* a key repeats */
/*
**
** keypad scanning program to decode the keypad via column to row
** sensing and decoding into a valid key code. This routine is
** designed to be called repeatively by a timed interrupt routine
** to support keypad filtering, debounce, and key repeat/held
** down logic.
**
** The keypad connects to the microcontroller via the following 
** connections. The numbers in the lower corner of each button
** the logical local key code for the button in hexadecimal.
** The numbers in the upper corner of each button are the 
** trnslated radio key codes.
**
** Note that this module generates logical key codes from the
** translate table that are +1 in value from those defined for
** the equipment interface so that a code of zero can indicate that
** no key is pressed.
**
**
**                                                  
**                                                  
**  +-1----+    +-2----+    +-3----+    +-A----+    
**  |  1   |____|  2   |____|  3   |____| ESC  |_K4______ Row 0
**  | SW1  |    | SW2  |    | SW3  |    | SW4  |           P2.0
**  +----0-+    +----1-+    +----2-+    +----3-+            
**     |           |           |           |        
**  +-4----+    +-5----+    +-6----+    +-E----+            
**  |  4   |____|  5   |____|  6   |____| PREV |_K5______ Row 1
**  | SW5  |    | SW6  |    | SW7  |    | SW8  |           P2.1
**  +----4-+    +----5-+    +----6-+    +----7-+            
**     |           |           |           |        
**  +-7----+    +-8----+    +-9----+    +-F----+            
**  |  7   |____|  8   |____|  9   |____| NEXT |_K6______ Row 2
**  | SW9  |    | SW10 |    | SW11 |    | SW12 |           P2.2
**  +----8-+    +----9-+    +----A-+    +----B-+            
**     |           |           |           |        
**  +-C----+    +-0----+    +-D----+    +-B----+            
**  |  <   |____|  0   |____|  >   |____| ENT  |_K7______ Row 3
**  | SW13 |    | SW14 |    | SW15 |    | SW16 |           P2.3
**  +----C-+    +----D-+    +----E-+    +----F-+    
**     |           |           |           |       
**     |           |           |           |
**     |           |           |           +-----K3------ Col 3
**     |           |           |                           P2.7
**     |           |           |
**     |           |           +-----------------K2------ Col 2
**     |           |                                       P2.6
**     |           |
**     |           +-----------------------------K1------ Col 1
**     |                                                   P2.5
**     |
**     +-----------------------------------------K0------ Col 0
**                                                         P2.4
**
** The four rows K4-K7 are equipped with pullup resistors at the
** inputs to the microcontroller. In normal operation the 
** columns are held high and placed low one column at a time
** while looking at the row inputs and seeing if there is
** a key pressed.
**
** scan codes are composed from the row and columns as two 
** two bit pairs as RRCC to compose a nibble wise key code. 
**
*/

/* globals that handle keyboard state logic */
char key_code;                  /* logical key code found in matrix */
char key_flag;                  /* flag true of key_code has a key present */
                                /*  0 = no keypress present */
                                /* -1 = key in debounce state */
                                /* +1 = key is valid press */
#if REPEAT_ENABLE
  char key_cnt;                 /* used to count out the key repeat duration */
#endif
char key_inp;                   /* this holds new key code detected */
                                /* key fetch routine clears upon seeing key */

/*
**
** routine to initialize the board scan port logic to the inactive
** state. 
**
*/

void key_init(void)
{
    P2 = 0xFF;                      /* init all of keyboard port as inputs */

    key_code=0;                     /* clear keyboard status variables */
    key_flag=0;
#if REPEAT_ENABLE
      key_cnt=0;
#endif
    key_inp=0;
}

/* table to translate from the logical key numbers of the key matrix */
/* to the equipment matrix keycodes. note that the initializer is laid */
/* out in matrix that is like the key pad locatioms */

// setup whatever scan codes you want in here, Dont use zero for one of them
const char key_xlat[16]={
                          RKEY_1,      RKEY_2,     RKEY_3,     RKEY_ESC,
                          RKEY_4,      RKEY_5,     RKEY_6,     RKEY_PREV,
                          RKEY_7,      RKEY_8,     RKEY_9,     RKEY_NEXT,
                          RKEY_LEFT,   RKEY_0,     RKEY_RIGHT, RKEY_ENT,
                        };

/* this translates column number to low active column select bit */
const char col_xlat[4]={
                            0xe0,   /* column code 1110 */
                            0xd0,   /* column code 1101 */
                            0xb0,   /* column code 1011 */
                            0x70,   /* column code 0111 */
                        };

/* this prioritizes scan decode to row 3-2-1-0. codes in */
/* table encode as high two bits of a nibble key code */
const char row_xlat[16]={
                            0x0,     /* row code 0000 */
                            0x0,     /* row code 0001 */
                            0x4,     /* row code 0010 */
                            0x4,     /* row code 0011 */
                            0x8,     /* row code 0100 */
                            0x8,     /* row code 0101 */
                            0x8,     /* row code 0110 */
                            0x8,     /* row code 0111 */
                            0xc,     /* row code 1000 */
                            0xc,     /* row code 1001 */
                            0xc,     /* row code 1010 */
                            0xc,     /* row code 1011 */
                            0xc,     /* row code 1100 */
                            0xc,     /* row code 1101 */
                            0xc,     /* row code 1110 */
                            0xc,     /* row code 1111 */
                        };

/*
**
** routine to scan the keypad matrix to detect keys that 
** are pressed. This routine is designed to be called
** at a regular repeatitive rate. (100 Hz is recommended).
** a key is valid is detected for two successive calls
** to this routine. A key detection is signalled by placing
** the key code into the "key_inp" variable with the MSB set.
** A separate key fetch routine would see this flag set 
** capture the key and then clear the flag.
**
** The key scanner will repeat a key that is seen held
** down for an extended period of time causing repeated
** insertions of the code into the "key_inp" variable.
**
** This routine uses a single key lockout scheme and
** puts a priority on the scan order and stop at the 
** first key seen. Is multiple keys are pressed the
** highest priority one takes precidence.
**
*/

void key_scan(void)
{
    char col;
    char row;
    char key;

    for(col=0; col<4; col++)
    {
        P2=P2 | col_xlat[col];

        row=P2;                         /* fetch in the row data */

        row=(row&0x0f)^0x0f;            /* keep low bits and invert */
        if(row != 0)                    /* if a row bit set then some key */
        {
            key=row_xlat[row]+col;      /* get key code */
            key=key_xlat[key];          /* translate to radio code+1 */
            P2|=0xf0;                   /* force column bits high */
            if(key_flag == 0)           /* new key found */
            {
                key_flag=-1;            /* setup the debounce state */
                key_code=key;
                return;
            }
            if(key == key_code)         /* matching last time? */
            {
                if(key_flag < 0)        /* 2nd sighting of same key */
                {
                    key_flag=1;         /* show valid key code */
#if REPEAT_ENABLE
                    key_cnt=KEY_DELAY;  /* init for initial repeat */
#endif
                    key_inp=key;        /* set new key out */
                    return;
                }
#if REPEAT_ENABLE
                if(key_cnt-- <= 0)
                {
                    key_cnt=KEY_RATE;   /* set period to repeat */
                    key_inp=key;        /* show key press */
                }
#endif
                return;
            }
            else
            {
                key_flag=-1;            /* setup debounce for this new one */
                key_code=key;
                return;
            }
        }   
    }
    P2|=0xf0;                           /* force all column bits high */

    /* no key seen so remove indication of any key */
    key_code=0;
    key_flag=0;
#if REPEAT_ENABLE
    key_cnt=0;
#endif
}

/*
** 
** routine to check if a particular key code is being held down
** for an external check for a repeat function of sorts.
**
*/

char keydown(char key)
{
    if((key_flag > 0) && (key == key_code))
    {
        /* show that key is pressed */
        return(1);
    }

    /* show that this key is not pressed */
    return(0);
}


/*
** 
** function to get a key code if any present.
** this will return the key code value and that will 
** valid of > 0. A return value of zero indicates that no
** key is pressed.
**
*/

char getkey(void)
{
    char key;

    if(key_inp)
    {
        key=key_inp;
        key_inp=0;
        return(key);
    }
    return(0);
}

/*
**
** routine to check is a key is present
** this will return a zero value if mo
** key is present
**
*/

char chkkey(void)
{
    if(key_inp)
    {
        return(1);      /* key is ready */
    }
    return(0);          /* no key ready */
}

 



List of 24 messages in thread
TopicAuthorDate
Keypad interface problem: My code not working..            01/01/70 00:00      
   Check in a simulator            01/01/70 00:00      
      RE:            01/01/70 00:00      
         Care for details            01/01/70 00:00      
            Formatted code            01/01/70 00:00      
            RE: i dint check the bounce            01/01/70 00:00      
               Bounce vital to think about            01/01/70 00:00      
                  Do document            01/01/70 00:00      
                     re: documentation prob            01/01/70 00:00      
                     Fixing prob:            01/01/70 00:00      
                        Did you search?            01/01/70 00:00      
                           RE: the search tool here is not the most powerful            01/01/70 00:00      
                           Karas's Keypad Scanner Code In C - detabbed            01/01/70 00:00      
                     Properly documented code            01/01/70 00:00      
                        Reasons and assumptions            01/01/70 00:00      
                           Per, you implied, but did not say            01/01/70 00:00      
   dangerous loops            01/01/70 00:00      
   code???            01/01/70 00:00      
   RE: now am modified my code            01/01/70 00:00      
      How to post legible source code            01/01/70 00:00      
         unfortunately, that does not add comments            01/01/70 00:00      
         re: thanks now i got how to insert code            01/01/70 00:00      
   Scanning Keypad            01/01/70 00:00      
   How to scan Keypad            01/01/70 00:00      

Back to Subject List