/* p3_4.c: Matrix keypad detect * * This program checks a 4x4 matrix keypad to see whether * a key is pressed or not. When a key is pressed, it turns * on the yellow LED0. * * PortB 07-04 are connected to the columns and PortB 3-0 are connected * to the rows of the keypad. The columns are used for inputs while * the rows are used for excitation outputs. * * Tested with Atmel Studio 7 v7.0.1006 and Keil MDK-ARM v5.21a */ #include "samd21.h" void delay(void); void keypad_init(void); char keypad_kbhit(void); int main(void) { keypad_init(); REG_PORT_DIRSET1 = 0x40000000; /* make PB30 output for LED0 */ while(1) { if (keypad_kbhit() != 0) /* if a key is pressed */ REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED0 */ else REG_PORT_OUTSET1 = 0x40000000; /* turn off LED0 */ } } /* this function initializes PortB7-0 that is connected to the keypad. * All pins are configured as GPIO input pin. The column pins have * the pull-up resistors enabled. */ void keypad_init(void) { int i; unsigned char* ARRAY_PORT_PINCFG1 = (unsigned char*)®_PORT_PINCFG1; REG_PORT_DIRSET1 = 0x0000000F; /* PB03-00 output */ REG_PORT_DIRCLR1 = 0x000000F0; /* PB07-04 input */ for (i = 4; i < 8; i++) ARRAY_PORT_PINCFG1[i] |= 6; /* enable PB07-04 input buffer with pull */ REG_PORT_OUTSET1 = 0x000000F0; /* PB07-04 pull-up */ } /* This is a non-blocking function. * If a key is pressed, it returns 1. Otherwise, it returns a 0. */ char keypad_kbhit(void) { int col; REG_PORT_DIRSET1 = 0x0F; /* make all row pins output */ REG_PORT_OUTCLR1 = 0x0F; /* drive all row pins low */ delay(); /* wait for signals to settle */ col = REG_PORT_IN1 & 0xF0; /* read all column pins */ REG_PORT_OUTSET1 = 0x0F; /* drive all rows high before disable them */ REG_PORT_DIRCLR1 = 0x0F; /* make all row pins input */ if (col == 0xF0) /* if all columns are high */ return 0; /* no key pressed */ else return 1; /* a key is pressed */ } /* make a small delay */ void delay(void) { __asm("nop"); }