Connecting 3x4 membrane keypad to STM32F401RE STMicroelectronics board in the STM32CubeIDE
On this keypad the first four pins are the rows from 1 to 4. The next three pins are the columns 1, 2, and 3, as seen on the photo below.
Next we create an empty STM32 Project for the STM32F401RE board in the STM32CubeIDE. We activate the USART2 in the Connectivity section as Asynchronous.
For the four rows of the keypad we assign the pins: PB12, PB13, PB, 14, PB15 as GPIO_Input, and for the three columns we assign the pins: PC6, PC7, PC8, as GPIO_Output. Rows' pins we pull down, and the columns' pins - pull up.
Next we connect the keypad display to the board. For this we download from the STMicroelectronics's website, st.com, the file User Manual STM32 Nucleo-64 board UM1724 (en.DM00105823.pdf) and look up the hardware pins configuration for the F401RE on the page #32. We need four pins: PB12, PB13, PB, 14, PB15 for the rows, and three pins: PC6, PC7, PC8 for the columns. Here is the print-screen of the page #32:
Basically all work is done by our function getKey(void), which we add to the file main.c in the folder Core/Src/.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <Stdio.h>
#define KEYPAD_NO_PRESSED 0xFF
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
uint8_t getKey(void) {
HAL_GPIO_WritePin(Col1_GPIO_Port, Col1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Col2_GPIO_Port, Col2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Col3_GPIO_Port, Col3_Pin, GPIO_PIN_RESET);
if (HAL_GPIO_ReadPin(Row1_GPIO_Port, Row1_Pin) == 1) {
return 1;
}
if (HAL_GPIO_ReadPin(Row2_GPIO_Port, Row2_Pin) == 1) {
return 4;
}
if (HAL_GPIO_ReadPin(Row3_GPIO_Port, Row3_Pin) == 1) {
return 7;
}
if (HAL_GPIO_ReadPin(Row4_GPIO_Port, Row4_Pin) == 1) {
return 42;
}
HAL_GPIO_WritePin(Col1_GPIO_Port, Col1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Col2_GPIO_Port, Col2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(Col3_GPIO_Port, Col3_Pin, GPIO_PIN_RESET);
if (HAL_GPIO_ReadPin(Row1_GPIO_Port, Row1_Pin) == 1) {
return 2;
}
if (HAL_GPIO_ReadPin(Row2_GPIO_Port, Row2_Pin) == 1) {
return 5;
}
if (HAL_GPIO_ReadPin(Row3_GPIO_Port, Row3_Pin) == 1) {
return 8;
}
if (HAL_GPIO_ReadPin(Row4_GPIO_Port, Row4_Pin) == 1) {
return 0;
}
HAL_GPIO_WritePin(Col1_GPIO_Port, Col1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Col2_GPIO_Port, Col2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(Col3_GPIO_Port, Col3_Pin, GPIO_PIN_SET);
if (HAL_GPIO_ReadPin(Row1_GPIO_Port, Row1_Pin) == 1) {
return 3;
}
if (HAL_GPIO_ReadPin(Row2_GPIO_Port, Row2_Pin) == 1) {
return 6;
}
if (HAL_GPIO_ReadPin(Row3_GPIO_Port, Row3_Pin) == 1) {
return 9;
}
if (HAL_GPIO_ReadPin(Row4_GPIO_Port, Row4_Pin) == 1) {
return 35;
}
return KEYPAD_NO_PRESSED;
}
uint8_t key;
char bfr[2];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
key = getKey();
if (key != KEYPAD_NO_PRESSED) {
if (key != 35 && key != 42) {
sprintf(bfr, "%u", key);
HAL_UART_Transmit(&huart2, (uint8_t*) bfr, sizeof(bfr) - 1, 10);
} else if (key == 42) {
HAL_UART_Transmit(&huart2, (uint8_t*) "*", 1, 1000);
} else if (key == 35) {
HAL_UART_Transmit(&huart2, (uint8_t*) "#", 1, 1000);
}
}
HAL_Delay(400);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
I recorded a short video of how the keypad works with the STM32 Nucleo-F401RE board and with this code: