HAL library 3- DELAY for STM32Fxxx
Delay functions are needed in your program, no matter how optimized and fast program you wanna do.
Delay functions
I’ve updated my delay library to support milliseconds and microseconds delays. Milliseconds based delay is done using systick timer which makes interrupts every 1ms generated by HAL library. For microseconds based delay, DWT cycle counter is used to get maximal optimized delay.
DWT unit is for F4 and F7 only, F0 series does not have DWT, because of Cortex-M0.
Software timers
Library supports software timers generation. Software timer has resolution of 1ms and counts down. It can be used to generate events each X milliseconds in your project.
Library
Features
- Delay for amount of milliseconds
- Delay for amount of microseconds
- Software timers with callback support
Dependencies
- HAL
- TM
- STM32Fxxx HAL
- defines.h
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
/** * @defgroup TM_DELAY_Typedefs * @brief Library Typedefs * @{ */ /** * @brief Custom timer structure */ typedef struct _TM_DELAY_Timer_t { uint32_t ARR; /*!< Auto reload value */ uint32_t AR; /*!< Set to 1 if timer should be auto reloaded when it reaches zero */ uint32_t CNT; /*!< Counter value, counter counts down */ uint8_t CTRL; /*!< Set to 1 when timer is enabled */ void (*Callback)(struct _TM_DELAY_Timer_t*, void *); /*!< Callback which will be called when timer reaches zero */ void* UserParameters; /*!< Pointer to user parameters used for callback function */ } TM_DELAY_Timer_t; /** * @} */ /** * @defgroup TM_DELAY_Variables * @brief Library variables * @{ */ extern __IO uint32_t TM_Time2; extern __IO uint32_t TM_Time; /** * @} */ /** * @defgroup TM_DELAY_Functions * @brief Library Functions * @{ */ /** * @brief Initializes delay functions * @param None * @retval DWT counter start status * - 0: DWT counter did not start, delay for microseconds won't work * - > 0: DWT counter works OK, delay is ready to use */ uint32_t TM_DELAY_Init(void); /** * @brief Delays for amount of micro seconds * @param micros: Number of microseconds for delay * @retval None */ __STATIC_INLINE void Delay(__IO uint32_t micros) { #if !defined(STM32F0xx) uint32_t start = DWT->CYCCNT; /* Go to number of cycles for system */ micros *= (HAL_RCC_GetHCLKFreq() / 1000000); /* Delay till end */ while ((DWT->CYCCNT - start) < micros); #else /* Go to clock cycles */ micros *= (SystemCoreClock / 1000000) / 5; /* Wait till done */ while (micros--); #endif } /** * @brief Delays for amount of milli seconds * @param millis: Number of milliseconds for delay * @retval None */ __STATIC_INLINE void Delayms(uint32_t millis) { /* Use HAL library for delay ms purpose */ HAL_Delay(millis); } /** * @brief Gets the TM_Time variable value * @param None * @retval Current time in milliseconds */ #define TM_DELAY_Time() (TM_Time) /** * @brief Sets value for TM_Time variable * @param time: Time in milliseconds * @retval None */ #define TM_DELAY_SetTime(time) (TM_Time = (time)) /** * @brief Gets the TM_Time2 variable value * @param None * @retval Current time in milliseconds * @note This is not meant for public use */ #define TM_DELAY_Time2() (TM_Time2) /** * @brief Sets value for TM_Time variable * @param time: Time in milliseconds * @retval None * @note This is not meant for public use */ #define TM_DELAY_SetTime2(time) (TM_Time2 = (time)) /** * @defgroup TM_DELAY_Timer_Functions * @brief Software timer functions * @{ */ /** * @brief Creates a new custom timer which has 1ms resolution * @note It uses @ref malloc for memory allocation for timer structure * @param ReloadValue: Number of milliseconds when timer reaches zero and callback function is called * @param AutoReloadCmd: If set to 1, timer will start again when it reaches zero and callback is called * @param StartTimer: If set to 1, timer will start immediately * @param *TM_DELAY_CustomTimerCallback: Pointer to callback function which will be called when timer reaches zero * @param *UserParameters: Pointer to void pointer to user parameters used as first parameter in callback function * @retval Pointer to allocated timer structure */ TM_DELAY_Timer_t* TM_DELAY_TimerCreate(uint32_t ReloadValue, uint8_t AutoReloadCmd, uint8_t StartTimer, void (*TM_DELAY_CustomTimerCallback)(struct _TM_DELAY_Timer_t*, void *), void* UserParameters); /** * @brief Deletes already allocated timer * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @retval None */ void TM_DELAY_TimerDelete(TM_DELAY_Timer_t* Timer); /** * @brief Stops custom timer from counting * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @retval Pointer to @ref TM_DELAY_Timer_t structure */ TM_DELAY_Timer_t* TM_DELAY_TimerStop(TM_DELAY_Timer_t* Timer); /** * @brief Starts custom timer counting * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @retval Pointer to @ref TM_DELAY_Timer_t structure */ TM_DELAY_Timer_t* TM_DELAY_TimerStart(TM_DELAY_Timer_t* Timer); /** * @brief Resets custom timer counter value * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @retval Pointer to @ref TM_DELAY_Timer_t structure */ TM_DELAY_Timer_t* TM_DELAY_TimerReset(TM_DELAY_Timer_t* Timer); /** * @brief Sets auto reload feature for timer * @note Auto reload features is used for timer which starts again when zero is reached if auto reload active * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @param AutoReload: Set to 1 if you want to enable AutoReload or 0 to disable * @retval Pointer to @ref TM_DELAY_Timer_t structure */ TM_DELAY_Timer_t* TM_DELAY_TimerAutoReloadCommand(TM_DELAY_Timer_t* Timer, uint8_t AutoReloadCmd); /** * @brief Sets auto reload value for timer * @param *Timer: Pointer to @ref TM_DELAY_Timer_t structure * @param AutoReloadValue: Value for timer to be set when zero is reached and callback is called * @note AutoReload feature must be enabled for timer in order to get this to work properly * @retval Pointer to @ref TM_DELAY_Timer_t structure */ TM_DELAY_Timer_t* TM_DELAY_TimerAutoReloadValue(TM_DELAY_Timer_t* Timer, uint32_t AutoReloadValue); /** * @} */ /** * @brief User function, called each 1ms when interrupt from timer happen * @note Here user should put things which has to be called periodically * @param None * @retval None * @note With __weak parameter to prevent link errors if not defined by user */ void TM_DELAY_1msHandler(void); /** * @} */ |
Example 1
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 |
/** * Keil project example for delay functions * * 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_disco.h" #include "tm_stm32_delay.h" int main(void) { /* Init system clock for maximum system speed */ TM_RCC_InitSystem(); /* Init HAL layer */ HAL_Init(); /* Init leds */ TM_DISCO_LedInit(); /* Init button */ TM_DISCO_ButtonInit(); /* Init delay */ TM_DELAY_Init(); while (1) { /* Turn off ALL leds */ TM_DISCO_LedToggle(LED_ALL); /* If button pressed */ if (TM_DISCO_ButtonPressed()) { /* Delayms */ Delayms(1000); } else { /* Delayus */ Delay(100000); } } } |
Example 2
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 |
/** * Keil project example for software timers with delay library * * 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_disco.h" #include "tm_stm32_delay.h" /* Create pointers for 2 timers */ TM_DELAY_Timer_t* SWTIM1; TM_DELAY_Timer_t* SWTIM2; /* References for function callbacks */ void SWTIM1_Callback(TM_DELAY_Timer_t* SWTIM, void* UserParameters); void SWTIM2_Callback(TM_DELAY_Timer_t* SWTIM, void* UserParameters); int main(void) { /* Init system clock for maximum system speed */ TM_RCC_InitSystem(); /* Init HAL layer */ HAL_Init(); /* Init leds */ TM_DISCO_LedInit(); /* Init button */ TM_DISCO_ButtonInit(); /* Init delay */ TM_DELAY_Init(); /* Create software timers */ /* 100ms with autoreload enabled, and start after it is created */ SWTIM1 = TM_DELAY_TimerCreate(100, 1, 1, SWTIM1_Callback, NULL); /* 150ms with autoreload enabled, and start after it is created */ SWTIM2 = TM_DELAY_TimerCreate(150, 1, 1, SWTIM2_Callback, NULL); while (1) { /* Do nothing */ /* Everything is performed in stm32fxxx_it.c function where callback functions are called for software timers */ } } /* Callback function for SWTIM1 */ void SWTIM1_Callback(TM_DELAY_Timer_t* SWTIM, void* UserParameters) { /* Toggle green led */ TM_DISCO_LedToggle(LED_GREEN); } /* Callback function for SWTIM2 */ void SWTIM2_Callback(TM_DELAY_Timer_t* SWTIM, void* UserParameters) { /* Toggle red led */ TM_DISCO_LedToggle(LED_RED); } |
Example 3
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 |
/** * Keil project example for delay functions for counting time * * 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_disco.h" #include "tm_stm32_delay.h" int main(void) { /* Init system clock for maximum system speed */ TM_RCC_InitSystem(); /* Init HAL layer */ HAL_Init(); /* Init leds */ TM_DISCO_LedInit(); /* Init delay */ TM_DELAY_Init(); while (1) { /* Each 500ms */ if (TM_DELAY_Time() >= 500) { /* Reset time */ TM_DELAY_SetTime(0); /* Toggle LED */ TM_DISCO_LedToggle(LED_ALL); } } } |
Projects are available on Github, download all libraries below.
STM32 libraries based on STM32Fxxx HAL drivers.
Recent comments