Requests for sample C code to deal with a matrix keypad is a recurrent question, what motivated me to share here some tips on an alternative implementation, not so widely employed.
This code brings some benefits:
Find bellow its implementation, fully tested on a 51 core, with a single adaptation for PIC core:
Important advice that presented code merely performs kernel scan feature, so that additional features ( e.g debounce ) must be performed for functions which instantiate it.
+++
This code brings some benefits:
- Allows reading combinations of multiple keys pressed at same row: 8(4 keys), 32(3keys), 48(2keys), 16(1key)
- A little faster, due just 2 nibble scans are performed, instead 16 bit scan, performed on the classical approach.
Find bellow its implementation, fully tested on a 51 core, with a single adaptation for PIC core:
Code:
/* ********************************************************************** */
#define ROW_MASK 0x0F
#define COLUMN_MASK 0xF0
#define NO_KEY 0x00
/* ********************************************************************** */
unsigned int ScanKey ( void )
{
unsigned int ReadingKey ;
TRISx = COLUMN_MASK ; // Set high nible as Input and low nible as Output ( not tested )
PORTx = ROW_MASK ; // Output "1" value for low nible
Delay ( STEADY_OUTPUT ) ; // wait a few for charging parasitic capacitance on Port
ReadingKey = (~( PORTx | COLUMN_MASK )) ; // Read only high nible at "ReadingKey"
if ( ReadingKey ) ; // If some key were pressed...
{
TRISx = ~COLUMN_MASK ; // Set low nible as Input and high nible as Output ( not tested )
PORTx = COLUMN_MASK ; // Output "1" value for high nible
Delay ( STEADY_OUTPUT ) ; // wait a few for charging parasitic capacitance on Port
ReadingKey |= (~( PORTx | ROW_MASK )) ; // Read only low nible at "ReadingKey" ( but now, add to previous read )
return ( ReadingKey ) ;
}
else return ( NO_KEY ) ; // ...otherwise, returns "0"
}
/* ********************************************************************** */
// KEY DEFINITIONS
// ---------------
//
// Px.4 Px.5 Px.6 Px.7
//
// Px.0 --0----1----2----3-
// | | | |
// Px.1 --4----5----6----7-
// | | | | ROW_MASK ( 00001111 )
// Px.2 --8----9----A----B-
// | | | |
// Px.3 --C----D----E----F-
//
// COLUMN_MASK ( 11110000 )
//
//
//
// KEY MAPPING
// -----------
//
// "0" [ BIT0 + 0 + 0 + 0 + BIT4 + 0 + 0 + 0 ]
// "1" [ BIT0 + 0 + 0 + 0 + 0 + BIT5 + 0 + 0 ]
// "2" [ BIT0 + 0 + 0 + 0 + 0 + 0 + BIT6 + 0 ]
// ... [ ... ]
// "E" [ 0 + 0 + 0 + BIT3 + 0 + 0 + BIT6 + 0 ]
// "F" [ 0 + 0 + 0 + BIT3 + 0 + 0 + 0 + BIT7 ]
// ...
// "0|3" [ BIT0 + 0 + 0 + 0 + BIT4 + 0 + 0 + BIT7 ]
// "4|6" [ 0 + BIT1 + 0 + 0 + BIT4 + 0 + BIT6 + 0 ]
//
// BITn = ( 1 << n )
Important advice that presented code merely performs kernel scan feature, so that additional features ( e.g debounce ) must be performed for functions which instantiate it.
+++