HAL library 04- EXTI for STM32Fxxx
EXTI library is used to set GPIO pin as external interrupt. It is designed to easily enable/disable interrupt and handle irq requests.
If you don’t know how EXTI works on STM32F4 or STM32F7 lines, you should take a look here.
Library
Features
- Allows up to 16 external interrupts at a time
- Allows to setup rising or falling edge for pin
- Allows to disable interrupt
- Single function for interrupt handling
- Works for STM32F0, STM32F4 and STM32F7 series
Dependencies
- HAL
- TM
- STM32Fxxx HAL
- defines.h
- GPIO
Library interrupt handling
STM32F4/7 has 7 interrupt handler function. They are all implemented in my library and all handlers calls one function, which is single callback function for different EXTI lines. On bottom example you will be able to see how to handle interrupts with single function.
For STM32F0, there are 3 interrupt handlers. They are also implemented in my library and all of them calls one function. Check example on the bottom.
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
/** * @defgroup TM_EXTI_Typedefs * @brief Library Typedefs * @{ */ /** * @brief Result enumeration */ typedef enum { TM_EXTI_Result_Ok = 0x00, /*!< Everything ok */ TM_EXTI_Result_Error /*!< An error has occured */ } TM_EXTI_Result_t; /** * @brief Interrupt trigger enumeration */ typedef enum { TM_EXTI_Trigger_Rising = 0x00, /*!< Trigger interrupt on rising edge on line, pull down resistor active */ TM_EXTI_Trigger_Falling, /*!< Trigger interrupt on falling edge on line, pull up resistor active */ TM_EXTI_Trigger_Rising_Falling /*!< Trigger interrupt on any edge on line, no pull resistor active */ } TM_EXTI_Trigger_t; /** * @} */ /** * @defgroup TM_EXTI_Functions * @brief Library Functions * @{ */ /** * @brief Attach external interrupt on specific GPIO pin * @note This function automatically enables the clock for GPIO peripheral and also sets pull resistors depending on trigger you use. * - Falling edge: pull up is enabled * - Rising edge: pull down is enabled * - Any edge: no pull activated * * @note You can attach only one GPIOx to specific GPIO_PIN. * In other words, GPIO_PIN_5 can not be attached to GPIOA and GPIOB at the same time. * If you will try that, my function will return error to you, because you have to detach GPIO_Line first and attach back on other GPIO port. * * @param *GPIOx: GPIO port where you want EXTI interrupt line * @param GPIO_Line: GPIO pin where you want EXTI interrupt line. Use OR (|) operator if you want to attach * interrupt on more than one GPIO pin at the same GPIOx at the same time. * @param trigger: Pin trigger source. This parameter can be a value of @ref TM_EXTI_Trigger_t enumeration * @retval Attach result: * - @arg TM_EXTI_Result_Ok: Everything ok, interrupt attached * - @arg TM_EXTI_Result_Error: An error occurred, interrupt was not attached * @note If you use more than one GPIO_Pin with OR (|) operator at single call and if GPIO_Pin can't be attached because * there is already one GPIO_Pin at this line, function will return error and other pins might not be initialized. * If function return @arg TM_EXTI_Result_Ok, then all pins are attached correctly. */ TM_EXTI_Result_t TM_EXTI_Attach(GPIO_TypeDef* GPIOx, uint16_t GPIO_Line, TM_EXTI_Trigger_t trigger); /** * @brief Detach GPIO pin from interrupt lines * @param GPIO_Line: GPIO line you want to disable. Valid GPIO is GPIO_Pin_0 to GPIO_Pin_15. * Use OR (|) operator if you want to detach interrupt in more than one GPIO pin at the same GPIOx at the same time. * @retval Detaching result: * - @arg TM_EXTI_Result_Ok: Everything ok * - @arg TM_EXTI_Result_Error: An error occurred */ TM_EXTI_Result_t TM_EXTI_Detach(uint16_t GPIO_Line); /** * @brief Clears all interrupts on EXTI line * @note It clears bits for external pins (bit 0 to bit 15) only! * It has no effect for internally connected peripherals (like RTC) to EXTI line * @param None * @retval None */ void TM_EXTI_DeInit(void); /** * @brief Creates software interrupt for specific external GPIO line * @note This also works for others EXTI lines from 16 to 23 * @param GPIO_Line: GPIO line where you want software interrupt * @retval None * @note Defined as macro for faster execution */ #define TM_EXTI_SoftwareInterrupt(GPIO_Line) (EXTI->SWIER |= (GPIO_Line)) /** * @brief EXTI Global handler * @note This function is called from TM EXTI library each time any interrupt occurs on EXTI line. * @note With __weak parameter to prevent link errors if not defined by user. * @param GPIO_Pin: GPIO Line where interrupt occurred so you can identify what to do * @retval None */ void TM_EXTI_Handler(uint16_t GPIO_Pin); /** * @} */ |
Example
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 |
/** * Keil project example for EXTI interrupts * * 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/STM32F7xx Keil packs are requred with HAL driver support * @stdperiph STM32F4xx/STM32F7xx HAL drivers required */ /* Include core modules */ #include "stm32fxxx_hal.h" /* Include my libraries here */ #include "defines.h" #include "tm_stm32_exti.h" #include "tm_stm32_disco.h" int main(void) { /* Init system clock for maximum system speed */ TM_RCC_InitSystem(); /* Init HAL layer */ HAL_Init(); /* Init leds */ TM_DISCO_LedInit(); /* Attach EXTI pin, enable both edges because of different boards support */ if (TM_EXTI_Attach(TM_DISCO_BUTTON_PORT, TM_DISCO_BUTTON_PIN, TM_EXTI_Trigger_Rising_Falling) == TM_EXTI_Result_Ok) { /* Turn on green LED */ TM_DISCO_LedOn(LED_GREEN); } else { /* Turn on RED led */ TM_DISCO_LedOn(LED_RED); } while (1) { /* Do nothing, wait user to press button */ } } /* Handle all EXTI lines */ void TM_EXTI_Handler(uint16_t GPIO_Pin) { /* Check proper line */ if (GPIO_Pin == TM_DISCO_BUTTON_PIN) { /* Toggle pin only if button is pressed */ if (TM_DISCO_ButtonPressed()) { /* Toggle LEDs if interrupt on button line happens */ TM_DISCO_LedToggle(LED_ALL); } } } |
Project is available on my Github account, download all libraries below.
STM32 libraries based on STM32Fxxx HAL drivers.
Recent comments