/* * Scan keypad and write the keycode to LEDs. * The matrix keypad of Wytec EduBase board is connected to * PORTD and PORTA. * * The connections between the keypad and Tiva LaunchPad are * row 0 PD0 * row 1 PD1 * row 2 PD2 * row 3 PD3 * col 0 PA2 * col 1 PA3 * col 2 PA4 * col 3 PA5 * * This program scans keypad and writes the keycode to the LEDs * on PORTB. The keycode is labeled 1 to 16. Since there are * only 4 LEDs, the bottom right key returns a 16 will not turn * on any LED. * */ #include "TM4C123GH6PM.h" void delayMs(int n); void delayUs(int n); void keypad_init(void); char keypad_getkey(void); int main(void) { char key; volatile unsigned char readback; // initialize ports connected to keypad keypad_init(); // enable PORTB 3-0 as output for LEDs SYSCTL->RCGCGPIO |= 0x02; // enable clock to GPIOB readback = SYSCTL->RCGCGPIO; // make sure the colock is enabled GPIOB->DIR |= 0x0F; // set PORTB 3-0 as output pins GPIOB->DEN |= 0x0F; // set PORTB 3-0 as digital pins while(1) { key = keypad_getkey(); // read the keypad GPIOB->DATA = key; // and write it to the LEDs } } /* * This function intializes the ports connected to the keypad. * PORTA is used as input port and PORTD is used as output port. */ void keypad_init(void) { SYSCTL->RCGCGPIO |= 0x01; // enable clock to GPIOA SYSCTL->RCGCGPIO |= 0x08; // enable clock to GPIOD GPIOA->DIR &= ~0x3C; // set column pins as input GPIOA->AMSEL &= ~0x3C; // disable analog function GPIOA->DEN |= 0x3C; // set column pins as digital pins GPIOD->AMSEL &= ~0x0F; // disable analog function GPIOD->DEN |= 0x0F; // set row pins 3-0 as digital pins } /* * This is a non-blocking function to read the keypad. * If a key is pressed, it returns a keycode. Otherwise, a zero * is returned. * PORTA is used as input port. There are pull-down resistors for * all pins used for keypad on the EduBase board. When these pins * are not active, they are low. * PORTD is used as output port that drives the keypad rows. * First all rows are driven high and the input pins are read. If no * key is pressed, it will read a zero. Otherwise, some key is pressed. * If any key is pressed, the program drives one row high at a time and * leave the rest of the rows inactive (float) then read the input pins. * Knowing which row is active and which pin is active, the program * can decide which key is pressed. */ char keypad_getkey(void) { int row, col; const char row_select[] = {0x01, 0x02, 0x04, 0x08}; // one of the row is active // check to see any key pressed first GPIOD->DIR |= 0x0F; // enable all rows GPIOD->DATA |= 0x0F; // set row data pins 3-0 all high col = GPIOA->DATA & 0x3C; // read all columns GPIOD->DIR &= ~0x0F; // disable all rows if (col == 0) return 0; // no key pressed, return a zero // If a key is pressed, it gets here to find out which key. // It activates one row at a time and read the input to see // which column is active. for (row = 0; row < 4; row++) { GPIOD->DIR &= ~0x0F; // disable all rows GPIOD->DIR |= row_select[row]; // enable one row GPIOD->DATA |= 0x0F; // turn the active row high delayUs(2); // wait for signal to settle col = GPIOA->DATA & 0x3C; // read all columns if (col != 0) break; // if one of the input is low, some key is pressed. } GPIOD->DIR &= ~0x0F; // disable all rows if (row == 4) return 0; // if we get here, no key is pressed // gets here when one of the rows has key pressed if (col == 0x04) return row * 4 + 1; // key in column 0 if (col == 0x08) return row * 4 + 2; // key in column 1 if (col == 0x10) return row * 4 + 3; // key in column 2 if (col == 0x20) return row * 4 + 4; // key in column 3 return 0; // just to be safe } // delay n milliseconds (16 MHz CPU clock) void delayMs(int n) { int i, j; for(i = 0 ; i < n; i++) for(j = 0; j < 3180; j++) {} // do nothing for 1 ms } // delay n microseconds (16 MHz CPU clock) void delayUs(int n) { int i, j; for(i = 0 ; i < n; i++) for(j = 0; j < 3; j++) {} // do nothing for 1 us } // This function is called by the startup assembly // code to perform system specific initialization tasks. void SystemInit(void) { // Grant coprocessor access // This is required since TM4C123G has // a floating point coprocessor SCB->CPACR |= 0x00f00000; }