Library 57- Buttons for STM32F4xx
I had some free time so I made a new library for web. It can handle buttons, connected to your STM32F4xx device.
It supports basically unlimited number of buttons with different triggering. Currently, callback functions can be called on these events:
- Button on pressed: Called directly when button is pressed
- Button normal press: Called when button is released after specific amount of time
- Button long press: Called when button is pressed for specific “long” amount of time
It uses malloc() to allocate memory, so you have to make sure that your heap is big enough. It also allows you to select state when button is pressed, high or low.
Currently, it does not support double click event but this will be done (I hope) in near future.
You just have to make sure, that your button is properly connected to STM device with capacitor and pull resistor!
Library
Features
- Supports buttons connected to STM32F4xx
- Support different button trigger events
Dependencies
- CMSIS
- STM32F4xx
- TM
- TM GPIO
- TM DELAY
- defines.h
- TM GPIO
Library uses some predefined constants which can be changed in your defines.h file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* Number of maximal supported buttons */ #ifndef BUTTON_MAX_BUTTONS #define BUTTON_MAX_BUTTONS 10 #endif /* Number of milliseconds for normal press detection */ #ifndef BUTTON_NORMAL_PRESS_TIME #define BUTTON_NORMAL_PRESS_TIME 100 #endif /* Number of milliseconds for long press detection */ #ifndef BUTTON_LONG_PRESS_TIME #define BUTTON_LONG_PRESS_TIME 1500 #endif |
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 73 74 75 |
/** * @defgroup TM_BUTTON_Typedefs * @brief Library Typedefs * @{ */ /** * @brief Button possible press types */ typedef enum { TM_BUTTON_PressType_OnPressed = 0x00, /*!< Button pressed */ TM_BUTTON_PressType_Normal, /*!< Normal press type, released */ TM_BUTTON_PressType_Long /*!< Long press type */ } TM_BUTTON_PressType_t; /** * @brief Button private structure */ typedef struct { GPIO_TypeDef* GPIOx; /*!< GPIOx PORT for button */ uint16_t GPIO_Pin; /*!< GPIO pin for button */ uint8_t GPIO_State; /*!< GPIO state for pin when pressed */ void (*ButtonHandler)(TM_BUTTON_PressType_t); /*!< Button function handler */ uint32_t StartTime; /*!< Time when button was pressed */ uint8_t LastStatus; /*!< Button status on last check */ uint8_t State; /*!< Current button state */ uint16_t PressNormalTime; /*!< Time in ms for normal press for button */ uint16_t PressLongTime; /*!< Time in ms for long press for button */ } TM_BUTTON_t; /** * @} */ /** * @defgroup TM_BUTTON_Functions * @brief Library Functions * @{ */ /** * @brief Initializes a new button to library * @note This library uses @ref malloc() to allocate memory, so make sure you have enough heap memory * @param *GPIOx: Pointer to GPIOx where button is located * @param GPIO_Pin: GPIO pin where button is located * @param ButtonState: Button state when it is pressed. * - 0: Button is low when pressed * - > 0: BUtton is high when pressed * @param *ButtonHandler: * @retval Button creation status: * - 0: Button was not created * - 0: Button created and saved to library, button pointer is returned */ TM_BUTTON_t* TM_BUTTON_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t ButtonState, void (*ButtonHandler)(TM_BUTTON_PressType_t)); /** * @brief Sets press timing values * @param *ButtonStruct: Pointer to @ref TM_BUTTON_t structure for button used * @param Normal: Time that button must be pressed to indicate normal press. Value is in milliseconds * @param Normal: Time that button must be pressed to indicate long press. Value is in milliseconds * @retval Pointer to @ref TM_BUTTON_t */ TM_BUTTON_t* TM_BUTTON_SetPressTime(TM_BUTTON_t* ButtonStruct, uint16_t Normal, uint16_t Long); /** * @brief Updates buttons. This function have to be called periodically * @note Function will automatically call callback functions for buttons * @param None * @retval None */ void TM_BUTTON_Update(void); /** * @} */ |
Example
Example below is done for Nucleo or Discovery board. 2 buttons on specific pins are initialized for use. Output is on PA2 for USART.
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 |
/** * Keil project template * * 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 * @conf PLL parameters are set in "Options for Target" -> "C/C++" -> "Defines" * @packs STM32F4xx Keil packs version 2.4.0 or greater required * @stdperiph STM32F4xx Standard peripheral drivers version 1.5.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_button.h" #include "tm_stm32f4_usart.h" /* Button 1 handler */ void BUTTON1_EventHandler(TM_BUTTON_PressType_t type); /* Button 2 handler */ void BUTTON2_EventHandler(TM_BUTTON_PressType_t type); int main(void) { /* Initialize system */ SystemInit(); /* Initialize delay */ TM_DELAY_Init(); /* Init USART2, TX: PA2, RX: PA3, 921600 baud */ TM_USART_Init(USART2, TM_USART_PinsPack_1, 921600); /* For Discovery boards */ /* GPIOA, pin 0, high (1) when pressed */ TM_BUTTON_Init(GPIOA, GPIO_PIN_0, 1, BUTTON1_EventHandler); /* For Nucleo boards */ /* GPIOA, pin 0, low (0) when pressed */ TM_BUTTON_Init(GPIOC, GPIO_PIN_13, 0, BUTTON2_EventHandler); while (1) { /* Update buttons */ TM_BUTTON_Update(); } } void BUTTON1_EventHandler(TM_BUTTON_PressType_t type) { /* Check button */ if (type == TM_BUTTON_PressType_OnPressed) { TM_USART_Puts(USART2, "Button 1 onPressed\n"); } else if (type == TM_BUTTON_PressType_Normal) { TM_USART_Puts(USART2, "Normal press detected on button 1\n"); } else { TM_USART_Puts(USART2, "Long press detected on button 1\n"); } } void BUTTON2_EventHandler(TM_BUTTON_PressType_t type) { /* Check button */ if (type == TM_BUTTON_PressType_OnPressed) { TM_USART_Puts(USART2, "Button 2 onPressed\n"); } else if (type == TM_BUTTON_PressType_Normal) { TM_USART_Puts(USART2, "Normal press detected on button 2\n"); } else { TM_USART_Puts(USART2, "Long press detected on button 2\n"); } } |
Project is available on my Github account, download library below.
Recent comments