No idea why it won't work. Don't know where to start.
I've look up everywhere to figure this out. I'm using an STM32F446RE controller with uVision software.
The basic objective of this project is 2. Write the complete code for printing the pressed key on Debug (printf) Viewer window using the functions in the prelab assignment. 3. Run your program that prompts the user to press a key on the keypad. 4. Read the keypad and print the number (or symbol) of the key that was pressed to the Debug (printf) Viewer window.
The pins I am "trying" to use for the row are 0,2,4,6 and the pins I am trying to use for the column are 8,10,12. Can't use HAL library.
#include "stm32f4xx.h"
#include <stdio.h>
void delay(void);
void delayMs(int n);
void keypad_init(void);
char keypad_getkey(void);
int main(void)
{
unsigned char key;
keypad_init();
while(1)
{
key = keypad_getkey(); //Function call to return key value
if(key != 0)
{
printf("KEY PRESSED: %c",key); //print key
}
}
}
void keypad_init(void)
{
RCC->AHB1ENR |= (1<<2); //enable clock C
GPIOC->MODER &= ~(uint32_t)(0x0333333); //clear pin mode to input
GPIOC->PUPDR = 0x01110000; //Enable pull up for column pins 8,10,12
}
char keypad_getkey(void)
{
int row,col;
const int row_mode[] = {0x00000001,0x00000010,0x0000100,0x00001000}; //One row is output pins 0,2,4,6
const int row_low[] = {0x00010000,0x00040000,0x00100000,0x00400000}; //One row is low pins 0,2,4,6
const int row_high[] = {0x00000001,0x00000004,0x00000010,0x00000040}; //One row is high pins 0,2,4,6
const char keypad[4][3] =
{
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
GPIOC->MODER = 0x00001111; //All row pins as output
GPIOC->BSRR = 0x00000055; //All pins as low for row
delay();
col = GPIOC->IDR & 0x0055; //Read all the column pins
GPIOC->MODER &= ~0x00003333; //Disable all row pins
if(col==0x0055) //if columns are high than no key is pressed
return 0;
for(row=0; row<4; row++)
{
GPIOC->MODER &= ~0x00003333; //disable row pins drive
GPIOC->MODER |= row_mode[row]; //enable one row at a time
GPIOC->BSRR = row_low[row]; //drive the active row low
delay();
col = GPIOC->IDR & 0x0055; //Read all the columns
GPIOC->BSRR = row_high[row]; //Make active row High
if(col != 0x0055) //if an input is low a key is pressed
break;
}
GPIOC->BSRR = 0x00000055; //drive all rows high
GPIOC->MODER &= ~0x00003333; //disable them
if (row == 4)
return 0;
for (int i = 0; i < 3; i++) //Check matrix table to determine output
{
if (col == 0x0E00 >> i)
return keypad[row][i];
}
return 0;
}
void delay(void)
{
int i;
for (i = 0; i < 20; i++) ;
}