HAL UART How to Use ¶
- group UART_How_To_Use
-
How to use the UART HAL module driver ¶
Use the UART HAL driver as follows:
1- Declare a hal_uart_handle_t handle structure, for example: ¶
hal_uart_handle_t huart;
2- Configure the low-level hardware (GPIO, CLOCK, NVIC, etc.): ¶
Enable the USARTx interface clock if you have not set USE_HAL_UART_CLK_ENABLE_MODEL to HAL_CLK_ENABLE_PERIPH_ONLY or HAL_CLK_ENABLE_PERIPH_PWR_SYSTEM (in those cases HAL_UART_Init() will enable the clock).
UART pins configuration:
Enable the clock for the UART GPIOs
Configure these UART pins as alternate function.
Configure the NVIC when using the interrupt process (HAL_UART_Transmit_IT() and HAL_UART_Receive_IT(), … APIs):
Configure the USARTx interrupt priority.
Enable the NVIC USARTx IRQ Channel.
Configure the DMA when using the DMA process (HAL_UART_Transmit_DMA() and HAL_UART_Receive_DMA(), … APIs):
Declare a DMA handle structure for the Tx or Rx channel.
Enable the DMAx interface clock.
Configure the declared DMA handle structure with the required Tx or Rx parameters.
Associate the initialized DMA handle with the UART handle with HAL_UART_SetTxDMA() or HAL_UART_SetRxDMA().
For each DMA channel (Tx and Rx), configure the corresponding NVIC line priority and enable it.
3- Initialize the UART driver by selecting a USARTx instance and calling HAL_UART_Init(). ¶
Depending on USE_HAL_UART_CLK_ENABLE_MODEL, HAL_UART_Init() can enable the USARTx clock. For example: HAL_UART_Init(&huart, HAL_UART1);
4- Declare a hal_uart_config_t structure, fill it, and then call HAL_UART_SetConfig(). For example: ¶
hal_uart_config_t my_config;
In the configuration structure, Program the baud rate, word length, stop bit, parity, prescaler value, hardware flow control, direction (Receiver/Transmitter), oversampling, and one-bit sampling.
Apply the configuration by calling HAL_UART_SetConfig(&huart, &my_config).
5- If required, enable a specific mode on the UART: ¶
Half-duplex mode with HAL_UART_EnableHalfDuplexMode()
Multiprocessor mode with HAL_UART_EnableMultiProcessorMode()
LIN mode with HAL_UART_EnableLINMode()
RS-485 mode with HAL_UART_EnableRS485Mode()
Or call UART advanced features (TX/RX pins swap, auto baud rate detection, …) with a set of different configuration functions.
6- Transfer APIs (Transmit and Receive) ¶
For USARTx I/O operations, polling, interrupt, and DMA are available within this driver.
Polling mode I/O operation
Send an amount of data in blocking mode using HAL_UART_Transmit()
Receive an amount of data in blocking mode using HAL_UART_Receive()
The communication is performed in polling mode. The HAL status for all data processing is returned by the same function after the transfer finishes or the timeout expires.
Interrupt mode I/O operation
Send an amount of data in non-blocking mode using HAL_UART_Transmit_IT() or HAL_UART_Transmit_IT_Opt()
At the end of transmission, HAL_UART_TxCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_TxCpltCallback().
Receive an amount of data in non-blocking mode using HAL_UART_Receive_IT() or HAL_UART_Receive_IT_Opt()
At the end of reception, HAL_UART_RxCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_RxCpltCallback().
In case of transfer error, HAL_UART_ErrorCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_ErrorCallback().
For interrupt transfers, call HAL_UART_IRQHandler() inside the USARTx IRQ handler
DMA mode I/O operation
Send an amount of data in non-blocking mode (DMA) using HAL_UART_Transmit_DMA() or HAL_UART_Transmit_DMA_Opt()
At the transmission half-transfer, HAL_UART_TxHalfCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_TxHalfCpltCallback().
At the end of transmission, HAL_UART_TxCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_TxCpltCallback().
Receive an amount of data in non-blocking mode (DMA) using HAL_UART_Receive_DMA() or HAL_UART_Receive_DMA_Opt()
At the reception half-transfer, HAL_UART_RxHalfCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_RxHalfCpltCallback().
At the end of reception, HAL_UART_RxCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_RxCpltCallback().
In case of transfer error, HAL_UART_ErrorCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_ErrorCallback().
Before starting DMA transfers, associate the DMA handle(s) with the UART handle using HAL_UART_SetTxDMA() and/or HAL_UART_SetRxDMA()
Advanced receive operations (optional)
Receive data until IDLE condition: HAL_UART_ReceiveToIdle(), HAL_UART_ReceiveToIdle_IT()
Receive data until timeout: HAL_UART_ReceiveUntilTMO(), HAL_UART_ReceiveUntilTMO_IT()
Receive data until character match: HAL_UART_ReceiveUntilCM(), HAL_UART_ReceiveUntilCM_IT()
When USE_HAL_UART_DMA is set to 1, also use the *_DMA() and *_DMA_Opt() variants
The sequential UART interface abort operations are listed below:
Abort a polling UART process communication using HAL_UART_Abort()
Abort an IT UART process communication with Interrupt using HAL_UART_Abort_IT()
Abort a transmit process using HAL_UART_AbortTransmit() or HAL_UART_AbortTransmit_IT()
Abort a receive process using HAL_UART_AbortReceive() or HAL_UART_AbortReceive_IT()
At the end of the abort IT process, HAL_UART_AbortCpltCallback() is executed, and you can add your own code by customizing the function pointer HAL_UART_AbortCpltCallback().
7- Callback registration ¶
When the compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 1U, configure the driver callbacks dynamically via your own method:
Callback name
Default value
Callback registration function
TxHalfCpltCallback
TxCpltCallback
RxHalfCpltCallback
RxCpltCallback
ErrorCallback
AbortCpltCallback
AbortTransmitCpltCallback
AbortReceiveCpltCallback
WakeupCallback
RxFifoFullCallback
TxFifoEmptyCallback
LINBreakCallback
ClearToSendCallback
To unregister a callback, register the default callback via the registration function.
By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_INIT, all callbacks are set to the corresponding default weak functions.
Register callbacks when the handle global_state is HAL_UART_STATE_INIT or HAL_UART_STATE_CONFIGURED.
When the compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0U or not defined, the callback registration feature is not available and weak callbacks are used, represented by the default value in the table above.
8- Acquire/Release the HAL UART handle ¶
When the compilation flag USE_HAL_MUTEX is set to 1, a multi-thread user application can acquire the whole UART HAL handle to execute a transmit or a receive process or a sequence of transmit/receive. When the given process or sequence ends, release the UART HAL handle.
The HAL acquire/release operations are based on the HAL OS abstraction layer (stm32_hal_os.c/.h osal):
Use HAL_UART_AcquireBus() to acquire the HAL UART handle.
Use HAL_UART_ReleaseBus() to release the HAL UART handle.
Note
In the following documentation, consider USARTx as a placeholder for every UART instance, USART instance, and LPUART instance.
Note
In DMA Tx configuration, also enable the USARTx IRQ to complete the DMA transfer.