UART Tx data using Poll Interrupt and DMA in STM32
I have already written a tutorial about How to use UART in STM32 but it wasn’t a very good detailed tutorial. So today I am writing this one here. It will only cover the transmission part of UART, Reception of data will be covered in next one.
I will use all three methods to transmit serial data here i.e
- using the poll —> HAL_UART_Transmit
- using the interrupt —> HAL_UART_Transmit_IT
- and using DMA —> HAL_UART_Transmit_DMA
Using the POLL method
Starting with the simplest one i.e using the POLL method. The data is transmitted using blocking mode i.e the CPU will block every other operation until the data transfer is complete. This method is good to use if you are only using UART and nothing else, otherwise all other operations will be affected.
To transmit data using POLL method, simply use
I am using toggle LED for you guys to better understand what happens when we try transmitting large data. This is best explained in the video, Please check it out. Also ’10’ is the timeout for the UART Tx here. At this point the data transmission is pretty quick and LED blinking rate is also constant.
Let’s try to transmit a large buffer now. I will keep the ‘timeout’ at ’10’ ms as it was before.
you will notice that LED blinking rate is constant but the complete data is not being transmitted.
This is because of the ‘timeout‘ we are using is 10 ms. Let’s increase the timeout now so that we can transfer the complete data.
Now the complete data is being transmitted, but the LED blinking rate decreases. This is because the UART is transmitting data in blocking mode and until the transfer completes, no other operation can take place. To overcome this problem we can use either INTERRUPT or DMA to transmit data.
USING the INTERRUPT
In interrupt mode, Transmission takes place in non-blocking mode or in the background. So the rest of the processes works as they should and when the data transmission is complete, a Tx Complete Callback is called where we can write instructions like “what to do after the transfer is complete?”.
You must watch the video if you want to see the working results. I can’t post them here. Check out the video at the end of the post.
In the above code, HAL_UART_TxCpltCallback will be called when the data transmission is complete and as you can see inside this function, I am again starting a new data transmission. This will result in continuous transmission of data and the rate of blinking will also remain constant as the data transfer takes place in non-blocking mode.
Let’s transmit data after some delay so that we can check whether the data transmitting is complete data…
NOW let’s say that we want the data to be transmitted after every 20 blinks of LED so that we can get enough time to analyze previously transmitted data before the new one comes.
Notice that I am calling HAL_UART_Transmit_IT inside the if loop, so that when 20 blinks are complete, than only the data gets transmitted. You will see that the complete data transmits after every 20 blinks.
USING the DMA
DMA also works somewhat same as interrupt, means that data transfer is in a non-blocking mode.
In DMA, when half the data gets transferred, a HALF TRANSFER COMPLETE INTERRUPT gets triggered and HAL_UART_TxHalfCpltCallback is called and when the data transfer completes, HAL_UART_TxCpltCallback is called.
Basically the idea behind this is when the second half of the data is being transmitted, we can write new data in the first half and that’s how DMA works as a circular buffer.
As you can see above that when the control will enter the HAL_UART_TxHalfCpltCallback function the data in the first half of the buffer should change and this happens when the second half is being transmitted. You can see this in the images below
You can also use toggle to continuously monitor this change.
- Interface WS2812 with STM32 April 16, 2021
- PWM with DMA in STM32 April 8, 2021
- Control Stepper motor using Rotary Angle Sensor March 21, 2021
- External Interrupt using Registers March 17, 2021
- STM32F103 Clock Setup using Registers March 3, 2021
- STM32 I2C Configuration using Registers February 26, 2021