Library 32- Matrix keypad on STM32F4
I have about 10 matrix keypads from ebay, like this or this. They are nice, because with 8 pins I can control 16 buttons in matrix way. I made a really simple library to handle pressed button and use it in projects.
Library supports long pressed button. This feature works like on PC.
You can adjust refresh rate how fast this works. Everything is below.
Library
Features
- Interface with 3 x 4 or 4 x 4 matrix keypad
- Supports long pressed buttons
- With style like on computer
Dependencies
- CMSIS
- STM32F4xx
- STM32F4xx RCC
- STM32F4xx GPIO
- TM
- TM GPIO
- defines.h
- TM GPIO
KEYPAD | STM32F4xx | Description |
---|---|---|
C1 | PD0 | Keypad COLUMN 1 |
C2 | PD1 | Keypad COLUMNÂ 2 |
C3 | PD2 | Keypad COLUMNÂ 3 |
C4 | PD3 | Keypad COLUMNÂ 4 (not used on small size) |
R1 | PC1 | Keypad ROWÂ 1 |
R2 | PC2 | Keypad ROWÂ 2 |
R3 | PC3 | Keypad ROWÂ 3 |
R4 | PC5 | Keypad ROWÂ 4 |
Because this library works on some basic variable counter based debounce, I made some defines to tweak that to your needs, according to device speed you are working with. STM32F4xx can work with maximum frequency of 84MHz, 100MHz, 168MHz and 180MHz, but can work with lower value.
Keypad structure looks like in table below:
- Large keypad size
COLUMN 1 COLUMNÂ 2 COLUMNÂ 3 COLUMNÂ 4 ROW 1 1 2 3 A ROW 2 4 5 6 B ROW 3 7 8 9 C ROW 4 * 0 # D - Small keypad size
Column 1 COLUMNÂ 2 COLUMNÂ 3 Row 1 1 2 3 ROW 2 4 5 6 ROW 3 7 8 9 ROW 4 * 0 #
I set all possible defines into one example. There are also settings on how to change pinout. I made some settings that I think are the best. You can still change it in defines.h file. Below is file’s example for this project:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* Columns */ /* Column 1 default */ #define KEYPAD_COLUMN_1_PORT GPIOD #define KEYPAD_COLUMN_1_PIN GPIO_PIN_0 /* Column 2 default */ #define KEYPAD_COLUMN_2_PORT GPIOD #define KEYPAD_COLUMN_2_PIN GPIO_PIN_1 /* Column 3 default */ #define KEYPAD_COLUMN_3_PORT GPIOD #define KEYPAD_COLUMN_3_PIN GPIO_PIN_2 /* Column 4 default */ #define KEYPAD_COLUMN_4_PORT GPIOD #define KEYPAD_COLUMN_4_PIN GPIO_PIN_3 /* Rows */ /* Row 1 default */ #define KEYPAD_ROW_1_PORT GPIOC #define KEYPAD_ROW_1_PIN GPIO_PIN_1 /* Row 2 default */ #define KEYPAD_ROW_2_PORT GPIOC #define KEYPAD_ROW_2_PIN GPIO_PIN_2 /* Row 3 default */ #define KEYPAD_ROW_3_PORT GPIOC #define KEYPAD_ROW_3_PIN GPIO_PIN_3 /* Row 4 default */ #define KEYPAD_ROW_4_PORT GPIOC #define KEYPAD_ROW_4_PIN GPIO_PIN_5 |
Functions and enumerations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/** * @defgroup TM_KEYPAD_Typedefs * @brief Library Typedefs * @{ */ /** * @brief Keypad button enumeration */ typedef enum { TM_KEYPAD_Button_0 = 0x00, /*!< Button 0 code */ TM_KEYPAD_Button_1 = 0x01, /*!< Button 1 code */ TM_KEYPAD_Button_2 = 0x02, /*!< Button 2 code */ TM_KEYPAD_Button_3 = 0x03, /*!< Button 3 code */ TM_KEYPAD_Button_4 = 0x04, /*!< Button 4 code */ TM_KEYPAD_Button_5 = 0x05, /*!< Button 5 code */ TM_KEYPAD_Button_6 = 0x06, /*!< Button 6 code */ TM_KEYPAD_Button_7 = 0x07, /*!< Button 7 code */ TM_KEYPAD_Button_8 = 0x08, /*!< Button 8 code */ TM_KEYPAD_Button_9 = 0x09, /*!< Button 9 code */ TM_KEYPAD_Button_STAR = 0x0A, /*!< Button START code */ TM_KEYPAD_Button_HASH = 0x0B, /*!< Button HASH code */ TM_KEYPAD_Button_A = 0x0C, /*!< Button A code. Only on large size */ TM_KEYPAD_Button_B = 0x0D, /*!< Button B code. Only on large size */ TM_KEYPAD_Button_C = 0x0E, /*!< Button C code. Only on large size */ TM_KEYPAD_Button_D = 0x0F, /*!< Button D code. Only on large size */ TM_KEYPAD_Button_NOPRESSED = KEYPAD_NO_PRESSED /*!< No button pressed */ } TM_KEYPAD_Button_t; /** * @brief Keypad size enumeration */ typedef enum { TM_KEYPAD_Type_Large = 0x00, /*!< Keypad 4x4 size */ TM_KEYPAD_Type_Small /*!< Keypad 3x4 size */ } TM_KEYPAD_Type_t; /** * @} */ /** * @defgroup TM_KEYPAD_Functions * @brief Library Functions * @{ */ /** * @brief Initializes keypad functionality * @param type: Keypad type you will use. This parameter can be a value of @ref TM_KEYPAD_Type_t enumeration * @retval None */ void TM_KEYPAD_Init(TM_KEYPAD_Type_t type); /** * @brief Reads keypad data * @param None * @retval Button status. This parameter will be a value of @ref TM_KEYPAD_Button_t enumeration */ TM_KEYPAD_Button_t TM_KEYPAD_Read(void); /** * @brief Updates keypad * @note This function must be called from interrupt routine every 1ms * @param None * @retval None */ void TM_KEYPAD_Update(void); /** * @} */ |
Example
This example was tested on large version of keypad (4 x 4). It works like this:
- Button 0: Toggle all leds. If you hold this button, leds will be toggled and you can see, how fast they are toggled.
- Button 1: Turn GREEN led on
- Button 2: Turn GREEN led off
- Button 3: Turn RED led on
- Button 4: Turn RED led off
- Button 5: Turn ORANGE led on
- Button 6: Turn ORANGE led off
- Button 7: Turn BLUE led on
- Button 8: Turn BLUE led off
- Button STAR: Turn on all leds
- Button HASH: Turn off all leds
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
/** * Keil project for matrix keypad 4x4 * * Before you start, select your target, on the right of the "Load" button * * @author Tilen Majerle * @email tilen@majerle.eu * @website http://stm32f4-discovery.net * @ide Keil uVision 5 * @packs STM32F4xx Keil packs version 2.2.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.4.0 or greater required */ /* Include core modules */ #include "stm32f4xx.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32f4_delay.h" #include "tm_stm32f4_disco.h" #include "tm_stm32f4_keypad.h" #include "tm_stm32f4_usart.h" #include <stdio.h> int main(void) { /* Create keypad instance */ TM_KEYPAD_Button_t Keypad_Button; char buff[20]; /* Initialize system */ SystemInit(); /* Init delay functions */ TM_DELAY_Init(); /* Initialize leds */ TM_DISCO_LedInit(); /* Initialize USART 1, TX: PB6 */ TM_USART_Init(USART1, TM_USART_PinsPack_2, 115200); /* Initialize matrix keyboard */ TM_KEYPAD_Init(TM_KEYPAD_Type_Large); while (1) { /* Read keyboard data */ Keypad_Button = TM_KEYPAD_Read(); /* Keypad was pressed */ if (Keypad_Button != TM_KEYPAD_Button_NOPRESSED) {/* Keypad is pressed */ switch (Keypad_Button) { case TM_KEYPAD_Button_0: /* Button 0 pressed */ TM_DISCO_LedToggle(LED_ALL); break; case TM_KEYPAD_Button_1: /* Button 1 pressed */ TM_DISCO_LedOn(LED_GREEN); break; case TM_KEYPAD_Button_2: /* Button 2 pressed */ TM_DISCO_LedOff(LED_GREEN); break; case TM_KEYPAD_Button_3: /* Button 3 pressed */ TM_DISCO_LedOn(LED_RED); break; case TM_KEYPAD_Button_4: /* Button 4 pressed */ TM_DISCO_LedOff(LED_RED); break; case TM_KEYPAD_Button_5: /* Button 5 pressed */ TM_DISCO_LedOn(LED_ORANGE); break; case TM_KEYPAD_Button_6: /* Button 6 pressed */ TM_DISCO_LedOff(LED_ORANGE); break; case TM_KEYPAD_Button_7: /* Button 7 pressed */ TM_DISCO_LedOn(LED_BLUE); break; case TM_KEYPAD_Button_8: /* Button 8 pressed */ TM_DISCO_LedOff(LED_BLUE); break; case TM_KEYPAD_Button_9: /* Button 9 pressed */ /* Do your stuff here */ break; case TM_KEYPAD_Button_STAR: /* Button STAR pressed */ TM_DISCO_LedOn(LED_ALL); break; case TM_KEYPAD_Button_HASH: /* Button HASH pressed */ TM_DISCO_LedOff(LED_ALL); break; case TM_KEYPAD_Button_A: /* Button A pressed, only on large keyboard */ /* Do your stuff here */ break; case TM_KEYPAD_Button_B: /* Button B pressed, only on large keyboard */ /* Do your stuff here */ break; case TM_KEYPAD_Button_C: /* Button C pressed, only on large keyboard */ /* Do your stuff here */ break; case TM_KEYPAD_Button_D: /* Button D pressed, only on large keyboard */ /* Do your stuff here */ break; default: break; } /* Send to user */ sprintf(buff, "Pressed: %u us\n", (uint8_t)Keypad_Button); TM_USART_Puts(USART1, buff); } } } /* 1ms handler */ void TM_DELAY_1msHandler(void) { /* Process keypad */ TM_KEYPAD_Update(); } |
Project is available on Github, download library below.
Recent comments