How To Receive UART Serial Data With STM32 – Interrupt – Polling

HAL. USART. Data transfer

In this tutorial, we’ll be discussing the USART / UART hardware in STM32 microcontrollers. Starting with an introduction to UART serial communication. And we’ll get a closer look at the STM32 USART hardware module and its internal functionalities, modes of operation, options, and configurations. In conclusion, we’ll take a look at the possible interrupt signals that can be triggered by the USART hardware. And that’s it for this theoretical tutorial. Next, we’ll do a couple of LABs to practice using USART in different projects for communication or even debugging.

Requirements

  • stm32f303 / Blue pill – 1
  • ST-Link Debugger – 1
  • FTDI – 1
  • Breadboard – 1
  • Jumper wires

Introduction To UART

Universal Asynchronous Receiver/Transmitter or UART for short represents the hardware circuitry (module) being used for serial communication. UART is sold/shipped as a standalone integrated circuit (IC) or as an internal module within microcontrollers. In this tutorial, we’re actually concerned with the internal UART module within STM32 Microcontrollers.

There are actually two forms of UART hardware as follows:

  • UART – Universal Asynchronous Receiver/Transmitter
  • USART – Universal Synchronous/Asynchronous Receiver/Transmitter

The Synchronous type of transmitters generates the data clock and sends it to the receiver which works accordingly in a synchronized manner. On the other hand, the Asynchronous type of transmitter generates the data clock internally. There is no incoming serial clock signal, so in order to achieve proper communication between the two ends, both of them must be using the same baud rate.


Today I will tell you what USART is and how to use it in STM32 controllers.

USART is a data transmission interface that occurs over two wires between two devices, in which the transmission and reception of data occurs over two separate wires.

Moreover, the data transfer contact of one device is connected to the data reception contact of the other and vice versa.

We will not study this interface in detail here, its protocol and other subtleties, this is all chewed in detail in the lesson for AVR .

In general, data transfer via USART occurs in this way

The bits indicated in curly braces may not be used in certain modes.

At the beginning of the diagram, we see that when the bus is not used and data on a certain wire is not transmitted or received, depending on the purpose of the contact, then this contact is in a high state. It is also customary to say that the passive state on the bus is high. Next comes the obligatory start bit. As you can see, it is directed downward, that is, at this time, the contact passes from a high state to a low state. How long a given bit lasts is no wonder to calculate. You need to divide 1 second by the speed set for transmitting and receiving data, which is measured in bits per second, or, as they call it, in baud. After the start bit time has expired, the controller will consider the following bits as informational. There can be from five to nine, depending on the mode. In general, 8 is most often used, since it is most convenient to transfer data by bytes. Well, here the state of the leg during the transmission of a certain information bit will be dictated by the information bit itself. That is, if you need to transfer one – then high, if zero – low. It is also important to note that the transmission of information bits starts with the least significant one, and then the most significant ones.

The next P bit is the parity bit. Depending on the mode, it may or may not be there. That is, when we transmit one block, it will be exposed, and the next one will be discarded, for even greater synchronization.

Then there are stop bits indicating that the transmission of the message is complete. There can be one or two data bits depending on the mode. These bits are transmitted using a high logic state on the leg. And then the process is repeated from the beginning, that is, we transmit the next message.

How can we do all this in practice, in order to connect our controller with a PC, provided that this interface does not exist on the PC. Such things are solved by means of interface converters or adapters.

These adapters are of different types depending on their manufacturers.

I will use all two methods to Receive serial data here i.e

  • using the poll —> HAL_UART_Receive
  • using the interrupt —> HAL_UART_Receive_IT

Using the POLL method

Starting with the simplest one i.e using the POLL method. The data is Received in 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 Receive data using POLL method, simply use

  /* USER CODE END 2 */
HAL_UART_Transmit(&huart3, (uint8_t *)" UART pOLLING METHOD\r\n", sizeof(" UART pOLLING METHOD\r\n"), 300);
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
HAL_UART_Receive(&huart3, rx_buffer,20, 300);
HAL_UART_Transmit(&huart3, rx_buffer, 20, 300);
    /*


Output

Using the INTERRUPT

In interrupt mode, Reception takes place in non-blocking mode or in the background. So the rest of the processes works as they should and when the data Reception is complete, a Rx Complete Callback is called where we can write instructions like “what to do after the Reception is complete?”.

Open #include “stm32f3xx_it.h”

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
	char ch;
  /* USER CODE END USART3_IRQn 0 */
	uint32_t isrflags   = READ_REG(huart3.Instance->ISR);
	uint32_t cr1its     = READ_REG(huart3.Instance->CR1);
	if (((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){
		huart3.Instance->ISR;
		ch = huart3.Instance->RDR;
		HAL_UART_Transmit(&huart3, &ch, 1, 1000);
	}
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */

  /* USER CODE END USART3_IRQn 1 */
}
HAL_UART_Transmit(&huart3, (uint8_t *)"UART INTERUpT\r\n", sizeof("UART INTERUpT\r\n"), 300);
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

Output

Using the POLL method

Using the INTERRUPT

Download Code:

UART Interrupt click here

UART Polling Click Here

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: