HAL Library 07- USART for STM32Fxxx
Here it is. UART library for HAL based libraries. If you don’t know, how UART work on STM32Fxxx devices, then you might take a look at my first library, where I also explained how to used it.
This library works successfully on F4 and F7 based devices for now. I will add support for F0 too as soon as possible.
Library
Features
- Supports up to 8 UART peripherals at a time
- Interrupt driven RX
- Support for different UART omdes
- Support for receiveing string
- Support for sending string/character/array
- Supports multiple predefined GPIO pins for specific UART or custom based pin initialization
Dependencies
- HAL
- TM
- STM32Fxxx HAL
- defines.h
- GPIO
- BUFFER
Pinouts
Below are possible USART pins. You select them on USART initialization.
Pins pack 1 | Pins pack 2 | Pins pack 3 | ||||
---|---|---|---|---|---|---|
U(S)ARTx | TX | RX | TX | RX | TX | RX |
USART1 | PA9 | PA10 | PB6 | PB7 | ||
USART2 | PA2 | PA3 | PD5 | PD6 | ||
USART3 | PB10 | PB11 | PC10 | PC11 | PD8 | PD9 |
UART4 | PA0 | PA1 | PC10 | PC11 | ||
UART5 | PC12 | PD2 | ||||
USART6 | PC6 | PC7 | PG14 | PG9 | ||
UART7 | PE8 | PE7 | PF7 | PF6 | ||
UART8 | PE1 | PE0 |
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 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
/** * @defgroup TM_USART_Typedefs * @brief USART Typedefs * @{ */ /** * @brief USART PinsPack enumeration to select pins combination for USART */ typedef enum { TM_USART_PinsPack_1 = 0x00, /*!< Select PinsPack1 from Pinout table for specific USART */ TM_USART_PinsPack_2, /*!< Select PinsPack2 from Pinout table for specific USART */ TM_USART_PinsPack_3, /*!< Select PinsPack3 from Pinout table for specific USART */ TM_USART_PinsPack_Custom /*!< Select custom pins for specific USART, callback will be called, look @ref TM_USART_InitCustomPinsCallback */ } TM_USART_PinsPack_t; /** * @brief USART Hardware flow control selection * @note Corresponsing pins must be initialized in case you don't use "None" options */ typedef enum { TM_USART_HardwareFlowControl_None = UART_HWCONTROL_NONE, /*!< No flow control */ TM_USART_HardwareFlowControl_RTS = UART_HWCONTROL_RTS, /*!< RTS flow control */ TM_USART_HardwareFlowControl_CTS = UART_HWCONTROL_CTS, /*!< CTS flow control */ TM_USART_HardwareFlowControl_RTS_CTS = UART_HWCONTROL_RTS_CTS /*!< RTS and CTS flow control */ } TM_USART_HardwareFlowControl_t; /** * @} */ /** * @defgroup TM_USART_Functions * @brief USART Functions * @{ */ /** * @brief Initializes USARTx peripheral and corresponding pins * @param *USARTx: Pointer to USARTx peripheral you will use * @param pinspack: This parameter can be a value of @ref TM_USART_PinsPack_t enumeration * @param baudrate: Baudrate number for USART communication * @retval None */ void TM_USART_Init(USART_TypeDef* USARTx, TM_USART_PinsPack_t pinspack, uint32_t baudrate); /** * @brief Initializes USARTx peripheral and corresponding pins with custom hardware flow control mode * @note Hardware flow control pins are not initialized. Easy solution is to use @arg TM_USART_PinsPack_Custom pinspack option * when you call @ref TM_USART_Init() function and initialize all USART pins at a time inside @ref TM_USART_InitCustomPinsCallback() * callback function, which will be called from my library * @param *USARTx: Pointer to USARTx peripheral you will use * @param pinspack: This parameter can be a value of @ref TM_USART_PinsPack_t enumeration * @param baudrate: Baudrate number for USART communication * @param FlowControl: Flow control mode you will use. This parameter can be a value of @ref TM_USART_HardwareFlowControl_t enumeration * @retval None */ void TM_USART_InitWithFlowControl(USART_TypeDef* USARTx, TM_USART_PinsPack_t pinspack, uint32_t baudrate, TM_USART_HardwareFlowControl_t FlowControl); /** * @brief Puts character to USART port * @param *USARTx: Pointer to USARTx peripheral you will use * @param c: character to be send over USART * @retval None */ static __INLINE void TM_USART_Putc(USART_TypeDef* USARTx, volatile char c) { /* Check USART */ if ((USARTx->CR1 & USART_CR1_UE)) { /* Wait to be ready, buffer empty */ USART_WAIT(USARTx); /* Send data */ USART_WRITE_DATA(USARTx, (uint16_t)(c & 0x01FF)); /* Wait to be ready, buffer empty */ USART_WAIT(USARTx); } } /** * @brief Puts string to USART port * @param *USARTx: Pointer to USARTx peripheral you will use * @param *str: Pointer to string to send over USART * @retval None */ void TM_USART_Puts(USART_TypeDef* USARTx, char* str); /** * @brief Sends data array to USART port * @param *USARTx: Pointer to USARTx peripheral you will use * @param *DataArray: Pointer to data array to be sent over USART * @param count: Number of elements in data array to be send over USART * @retval None */ void TM_USART_Send(USART_TypeDef* USARTx, uint8_t* DataArray, uint16_t count); /** * @brief Gets character from internal USART buffer * @param *USARTx: Pointer to USARTx peripheral you will use * @retval Character from buffer, or 0 if nothing in buffer */ uint8_t TM_USART_Getc(USART_TypeDef* USARTx); /** * @brief Get string from USART * * This function can create a string from USART received data. * * It generates string until "\n" is not recognized or buffer length is full. * * @note As of version 1.5, this function automatically adds 0x0A (Line feed) at the end of string. * @param *USARTx: Pointer to USARTx peripheral you will use * @param *buffer: Pointer to buffer where data will be stored from buffer * @param bufsize: maximal number of characters we can add to your buffer, including leading zero * @retval Number of characters in buffer */ uint16_t TM_USART_Gets(USART_TypeDef* USARTx, char* buffer, uint16_t bufsize); /** * @brief Check if character c is available in internal buffer * @param *USARTx: Pointer to USARTx peripheral you will use * @param c: character to check if it is in USARTx's buffer * @retval Character status: * - 0: Character was not found * - > 0: Character has been found in buffer */ uint8_t TM_USART_FindCharacter(USART_TypeDef* USARTx, uint8_t c); /** * @brief Checks if internal USARTx buffer is empty * @param *USARTx: Pointer to USARTx peripheral you will use * @retval Buffer empty status: * - 0: Buffer is not empty * - > 0: Buffer is empty */ uint8_t TM_USART_BufferEmpty(USART_TypeDef* USARTx); /** * @brief Checks if internal USARTx buffer is full * @param *USARTx: Pointer to USARTx peripheral you will use * @retval Buffer full status: * - 0: Buffer is not full * - > 0: Buffer is full */ uint8_t TM_USART_BufferFull(USART_TypeDef* USARTx); /** * @brief Clears internal USART buffer * @param *USARTx: Pointer to USARTx peripheral you will use * @retval None */ void TM_USART_ClearBuffer(USART_TypeDef* USARTx); /** * @brief Sets custom character for @ref TM_USART_Gets() function to detect when string ends * @param *USARTx: Pointer to USARTx peripheral you will use * @param Character: Character value to be used as string end * @note Character will also be added at the end for your buffer when calling @ref TM_USART_Gets() function * @retval None */ void TM_USART_SetCustomStringEndCharacter(USART_TypeDef* USARTx, uint8_t Character); /** * @brief Callback for custom pins initialization for USARTx. * * When you call @ef TM_USART_Init() function, and if you pass @arg TM_USART_PinsPack_Custom to function, * then this function will be called where you can initialize custom pins for USART peripheral. * @note With __weak parameter to prevent link errors if not defined by user * @param *USARTx: Pointer to USARTx peripheral you will use for initialization * @param AlternateFunction: Alternate function number which should be used for GPIO pins * @retval None */ void TM_USART_InitCustomPinsCallback(USART_TypeDef* USARTx, uint16_t AlternateFunction); /** * @brief Callback function for receive interrupt on USART1 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_USART1_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on USART2 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_USART2_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on USART3 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_USART3_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on UART4 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_UART4_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on UART5 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_UART5_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on USART6 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_USART6_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on UART7 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_UART7_ReceiveHandler(uint8_t c); /** * @brief Callback function for receive interrupt on UART8 in case you have enabled custom USART handler mode * @note With __weak parameter to prevent link errors if not defined by user * @param c: character received via USART * @retval None */ __weak void TM_UART8_ReceiveHandler(uint8_t c); /** * @} */ |
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 |
/** * Keil project example for USART peripheral * * 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" #include "tm_stm32_usart.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 USART, TX: PC6, RX: PC7, 921600 bauds */ TM_USART_Init(USART6, TM_USART_PinsPack_1, 921600); /* Put test string */ TM_USART_Puts(USART6, "Hello world\n"); while (1) { /* Check if anything received */ while (!TM_USART_BufferEmpty(USART6)) { /* Send data back from buffer */ TM_USART_Putc(USART6, TM_USART_Getc(USART6)); } } } |
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 |
/** * Keil project example for custom pins initialization * * 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" #include "tm_stm32_usart.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 USART, Pins not initialized yet, 921600 bauds */ TM_USART_Init(USART6, TM_USART_PinsPack_Custom, 921600); /* Put test string */ TM_USART_Puts(USART6, "Hello world\n"); while (1) { /* Check if anything received */ while (!TM_USART_BufferEmpty(USART6)) { /* Send data back from buffer */ TM_USART_Putc(USART6, TM_USART_Getc(USART6)); } } } /* USART Custom pins callback function */ void TM_USART_InitCustomPinsCallback(USART_TypeDef* USARTx, uint16_t AlternateFunction) { /* Check for proper USART */ if (USARTx == USART6) { /* Init pins for USART 6 */ TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_6 | GPIO_PIN_7, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, AlternateFunction); } } |
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 45 46 47 48 49 50 51 52 |
/** * Keil project example for USART string receive and send * * 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" #include "tm_stm32_usart.h" /* Buffer array */ char mybuffer[100]; 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 USART, TX: PC6, RX: PC7, 921600 bauds */ TM_USART_Init(USART6, TM_USART_PinsPack_1, 921600); /* Put test string */ TM_USART_Puts(USART6, "Hello world\n"); while (1) { /* Check if string received */ /* Waiting for \n at the end of string */ if (TM_USART_Gets(USART6, mybuffer, sizeof(mybuffer))) { /* Send string back */ TM_USART_Puts(USART6, mybuffer); } } } |
Projects are available on Github, download all libraries below.
STM32 libraries based on STM32Fxxx HAL drivers.
Recent comments